Version Description
- bug fixing in RTL interface
- adding subscription box
Download this release
Release Info
Developer | osamaesh |
Plugin | Visitors Traffic Real Time Statistics |
Version | 1.17 |
Comparing to | |
See all releases |
Code changes from version 1.3 to 1.17
- Visitors-Traffic-Real-Time-Statistics.php +131 -10
- WPHitsCounter.php +1031 -470
- ahc_about.php +0 -0
- ahc_help.php +0 -0
- ahc_settings.php +5 -0
- css/ar_css.css +1 -1
- css/en_newcss.css +0 -115
- css/eng_css.css +222 -0
- css/{en_css.css → engl_css.css} +120 -18
- css/jquery.jqplot.min.css +1 -0
- css/sweetalerts.css +1 -0
- database_basics_data.php +2 -1
- functions.php +2061 -1012
- images/247.png +0 -0
- images/24_7.ico +0 -0
- images/Icon-user.png +0 -0
- images/Spinner-1s-200px.svg +49 -0
- images/VisualEditor_-_Icon_-_Search.svg.png +0 -0
- images/browsers_nodata.png +0 -0
- images/contact-center-reporting-icon.png +0 -0
- images/decrease.png +0 -0
- images/down.png +0 -0
- images/increase.png +0 -0
- images/latestwords_nodata.png +0 -0
- images/live.gif +0 -0
- images/logo.png +0 -0
- images/myheaderbg.png +0 -0
- images/new_ticket_title.jpg +0 -0
- images/newticket.png +0 -0
- images/online.png +0 -0
- images/openW.jpg +0 -0
- images/openW.png +0 -0
- images/output_ZD6GUg-1-2.gif +0 -0
- images/plugin-1.png +0 -0
- images/plugin-2.png +0 -0
- images/plugin-3.png +0 -0
- images/plugin-4.png +0 -0
- images/plugin-5.png +0 -0
- images/plugin-6.png +0 -0
- images/recent_nodata.png +0 -0
- images/se_nodata.png +0 -0
- images/searchengin.png +0 -0
- images/searchengins.png +0 -0
- images/settings.jpg +0 -0
- images/stats.png +0 -0
- images/stats2.png +0 -0
- images/stats2.psd +0 -0
- images/stats3.png +0 -0
- images/topref_nodata.png +0 -0
- images/up.png +0 -0
- images/upgrade.png +0 -0
- images/visitors.png +0 -0
- images/visits.png +0 -0
- images/vtrts.png +0 -0
- images/vtrts_ads.gif +0 -0
- images/wordpress-plugins.png +0 -0
- init.php +55 -25
- js/ahc_jqscripts.js +358 -0
- js/front.js +59 -0
- js/jqplot.canvasAxisLabelRenderer.min.js +3 -0
- js/jqplot.canvasAxisTickRenderer.min.js +3 -0
- js/jqplot.canvasTextRenderer.min.js +3 -0
- js/jqplot.dateAxisRenderer.min.js +3 -0
- js/jqplot.enhancedLegendRenderer.min.js +3 -0
- js/jqplot.highlighter.min.js +3 -0
- js/jqplot.pieRenderer.min.js +3 -0
- js/jquery.jqplot.min.js +8 -0
- js/js.js +0 -183
- js/sweetalert.min.js +1 -0
- lang/ar_lang.php +23 -23
- lang/en_lang.php +23 -23
- lang/js/ar_lang.js +3 -3
- lang/js/en_lang.js +3 -3
- lib/Chart_js/.gitignore +0 -7
- lib/Chart_js/CONTRIBUTING.md +0 -20
- lib/Chart_js/Chart.js +0 -3379
- lib/Chart_js/Chart.min.js +5 -9
- lib/Chart_js/bower.json +0 -11
- lib/Chart_js/docs/00-Getting-Started.md +0 -200
- lib/Chart_js/docs/01-Line-Chart.md +0 -160
- lib/Chart_js/docs/02-Bar-Chart.md +0 -143
- lib/Chart_js/docs/03-Radar-Chart.md +0 -177
- lib/Chart_js/docs/04-Polar-Area-Chart.md +0 -172
- lib/Chart_js/docs/05-Pie-Doughnut-Chart.md +0 -158
- lib/Chart_js/docs/06-Advanced.md +0 -152
- lib/Chart_js/docs/07-Notes.md +0 -42
- lib/Chart_js/gulpfile.js +0 -131
- lib/Chart_js/package.json +0 -24
- lib/Chart_js/samples/bar.html +0 -48
- lib/Chart_js/samples/doughnut.html +0 -67
- lib/Chart_js/samples/line.html +0 -54
- lib/Chart_js/samples/pie.html +0 -58
- lib/Chart_js/samples/polar-area.html +0 -60
- lib/Chart_js/samples/radar.html +0 -53
- lib/Chart_js/src/Chart.Bar.js +0 -294
- lib/Chart_js/src/Chart.Core.js +0 -1943
- lib/Chart_js/src/Chart.Doughnut.js +0 -184
- lib/Chart_js/src/Chart.Line.js +0 -366
- lib/Chart_js/src/Chart.PolarArea.js +0 -248
- lib/Chart_js/src/Chart.Radar.js +0 -343
- lib/Chart_js/utils.js +147 -0
- lib/bootstrap/css/bootstrap-rtl.min.css +8 -0
Visitors-Traffic-Real-Time-Statistics.php
CHANGED
@@ -1,21 +1,142 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
-
Plugin Name:
|
4 |
-
Description: Hits counter that shows analytical numbers of your WordPress site visitors and hits.
|
5 |
Author: wp-buy
|
6 |
Author URI: https://www.wp-buy.com/
|
7 |
-
Version: 1.
|
8 |
-
|
|
|
9 |
*/
|
10 |
|
11 |
-
define('AHC_PLUGIN_MAIN_FILE', __FILE__);
|
12 |
-
define('AHC_PLUGIN_ROOT_DIR', dirname(__FILE__));
|
13 |
|
14 |
-
require_once("functions.php");
|
15 |
-
require_once("init.php");
|
16 |
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
//--------------------------------------------
|
21 |
?>
|
1 |
<?php
|
2 |
/*
|
3 |
+
Plugin Name: Visitor Traffic Real Time Statistics
|
4 |
+
Description: Hits counter that shows analytical numbers of your WordPress site visitors and hits.
|
5 |
Author: wp-buy
|
6 |
Author URI: https://www.wp-buy.com/
|
7 |
+
Version: 1.17
|
8 |
+
Text Domain: vtrts-free
|
9 |
+
Domain Path: /languages
|
10 |
*/
|
11 |
|
|
|
|
|
12 |
|
|
|
|
|
13 |
|
14 |
+
|
15 |
+
define('AHCFREE_PLUGIN_MAIN_FILE', __FILE__);
|
16 |
+
define('AHCFREE_PLUGIN_ROOT_DIR', dirname(__FILE__));
|
17 |
+
|
18 |
+
require_once(AHCFREE_PLUGIN_ROOT_DIR. "/functions.php");
|
19 |
+
require_once(AHCFREE_PLUGIN_ROOT_DIR."/init.php");
|
20 |
+
|
21 |
+
if( !function_exists('get_plugin_data') ){
|
22 |
+
include_once(ABSPATH . 'wp-includes/pluggable.php');
|
23 |
+
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
function ahcfree_plugin_action_links( $links ) {
|
28 |
+
|
29 |
+
$links = array_merge( array(
|
30 |
+
'<a href="' . esc_url( admin_url( '/admin.php?page=ahc_hits_counter_settings' ) ) . '">' . __( 'Settings', 'ahcfree' ) . '</a>',
|
31 |
+
'<a href="' . esc_url( admin_url( '/admin.php?page=ahc_hits_counter_menu_free' ) ) . '">' . __( 'Dashboard', 'ahcfree' ) . '</a>',
|
32 |
+
'<a target="_blank" href="' . esc_url('https://www.wp-buy.com/product/visitors-traffic-real-time-statistics-pro/' ) . '"><b style="color:green">' . __( 'Upgrade to PRO', 'ahcfree' ) . '</b></a>'
|
33 |
+
|
34 |
+
), $links );
|
35 |
+
|
36 |
+
return $links;
|
37 |
+
|
38 |
+
}
|
39 |
+
add_action( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'ahcfree_plugin_action_links' );
|
40 |
+
|
41 |
+
|
42 |
+
if ( function_exists('get_plugin_data') ) {
|
43 |
+
$woodhl_detail = get_plugin_data( __FILE__ );
|
44 |
+
$installed_version = get_option( 'visitors-traffic-real-time-statistics-free-version' );
|
45 |
+
if( $installed_version != $woodhl_detail['Version'] ){
|
46 |
+
add_action( 'plugins_loaded', 'ahcfix_init' );
|
47 |
+
update_option( 'visitors-traffic-real-time-statistics-free-version', $woodhl_detail['Version'] );
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
function ahcfree_HideMessageAjaxFunction()
|
53 |
+
{
|
54 |
+
add_option( 'ahcfree_upgrade_message','yes');
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
function ahcfree_after_plugin_row($plugin_file, $plugin_data, $status) {
|
59 |
+
|
60 |
+
if(get_option('ahcfree_upgrade_message') !='yes')
|
61 |
+
{
|
62 |
+
$class_name = $plugin_data['slug'];
|
63 |
+
|
64 |
+
$upgradeMsg = '<tr id="' .$class_name. '-plugin-update-tr" class="plugin-update-tr active">';
|
65 |
+
$upgradeMsg .= '<td colspan="3" class="plugin-update">';
|
66 |
+
$upgradeMsg .= '<div id="' .$class_name. '-upgradeMsg" class="update-message" style="background:#FFF8E5; padding-left:10px; border-left:#FFB900 solid 4px" >';
|
67 |
+
|
68 |
+
$upgradeMsg .= 'You are running visitor traffic free. To get more features (<b style="color:red">Online users, GEO locations and visitors on the map</b>), you can <a href="https://www.wp-buy.com/product/visitors-traffic-real-time-statistics-pro/#plugins-page" target="_blank"><strong>upgrade now</strong></a> or ';
|
69 |
+
|
70 |
+
$upgradeMsg .= '<span id="HideMe" style="cursor:pointer" ><a href="javascript:void(0)"><strong>dismiss</strong></a> this message</span>';
|
71 |
+
$upgradeMsg .= '</div>';
|
72 |
+
$upgradeMsg .= '</td>';
|
73 |
+
$upgradeMsg .= '</tr>';
|
74 |
+
|
75 |
+
|
76 |
+
echo $upgradeMsg;
|
77 |
+
?>
|
78 |
+
|
79 |
+
<script type="text/javascript">
|
80 |
+
jQuery(document).ready(function() {
|
81 |
+
var row = jQuery('#<?php echo $class_name;?>-plugin-update-tr').closest('tr').prev();
|
82 |
+
jQuery(row).addClass('update');
|
83 |
+
|
84 |
+
|
85 |
+
jQuery("#HideMe").click(function(){
|
86 |
+
|
87 |
+
jQuery("#<?php echo $class_name;?>-upgradeMsg").empty();
|
88 |
+
jQuery("#<?php echo $class_name;?>-upgradeMsg").removeAttr("style");
|
89 |
+
|
90 |
+
localStorage.setItem("vtrts_hide_upgrade_message", "hide_msg");
|
91 |
+
|
92 |
+
|
93 |
+
});
|
94 |
+
|
95 |
+
if(localStorage.getItem("vtrts_hide_upgrade_message") == "hide_msg")
|
96 |
+
{
|
97 |
+
|
98 |
+
jQuery("#<?php echo $class_name;?>-upgradeMsg").empty();
|
99 |
+
jQuery("#<?php echo $class_name;?>-upgradeMsg").removeAttr("style");
|
100 |
+
}
|
101 |
+
|
102 |
+
});
|
103 |
+
</script>
|
104 |
+
|
105 |
+
|
106 |
+
<?php
|
107 |
+
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
function ahcfree_row_meta( $meta_fields, $file ) {
|
112 |
+
|
113 |
+
if ( strpos($file,'Visitors-Traffic-Real-Time-Statistics.php') == false) {
|
114 |
+
|
115 |
+
return $meta_fields;
|
116 |
+
}
|
117 |
+
|
118 |
+
echo "<style>.pluginrows-rate-stars { display: inline-block; color: #ffb900; position: relative; top: 3px; }.pluginrows-rate-stars svg{ fill:#ffb900; } .pluginrows-rate-stars svg:hover{ fill:#ffb900 } .pluginrows-rate-stars svg:hover ~ svg{ fill:none; } </style>";
|
119 |
+
|
120 |
+
$plugin_rate = "https://wordpress.org/support/plugin/visitors-traffic-real-time-statistics/reviews/?rate=5#new-post";
|
121 |
+
$plugin_filter = "https://wordpress.org/support/plugin/visitors-traffic-real-time-statistics/reviews/?filter=5";
|
122 |
+
$svg_xmlns = "https://www.w3.org/2000/svg";
|
123 |
+
$svg_icon = '';
|
124 |
+
|
125 |
+
for ( $i = 0; $i < 5; $i++ ) {
|
126 |
+
$svg_icon .= "<svg xmlns='" . esc_url( $svg_xmlns ) . "' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg>";
|
127 |
+
}
|
128 |
+
|
129 |
+
$meta_fields[] = '<a href="' . esc_url( $plugin_filter ) . '" target="_blank"><span class="dashicons dashicons-thumbs-up"></span>' . __( 'Vote!', 'pluginrows' ) . '</a>';
|
130 |
+
$meta_fields[] = "<a href='" . esc_url( $plugin_rate ) . "' target='_blank' title='" . esc_html__( 'Rate', 'pluginrows' ) . "'><i class='pluginrows-rate-stars'>" . $svg_icon . "</i></a>";
|
131 |
+
|
132 |
+
return $meta_fields;
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
$path = plugin_basename( __FILE__ );
|
137 |
+
add_action("after_plugin_row_{$path}", 'ahcfree_after_plugin_row', 10, 3);
|
138 |
+
add_action( 'wp_ajax_ahcfree_HideMessageAjaxFunction', 'ahcfree_HideMessageAjaxFunction' );
|
139 |
+
add_filter( 'plugin_row_meta', 'ahcfree_row_meta', 10, 4 );
|
140 |
|
141 |
//--------------------------------------------
|
142 |
?>
|
WPHitsCounter.php
CHANGED
@@ -1,519 +1,1080 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
|
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
* @param string $page_title Optional
|
26 |
-
* @param string $post_type Optional
|
27 |
-
*/
|
28 |
-
public function __construct($page_id, $page_title = NULL, $post_type = NULL){
|
29 |
-
global $_SERVER;
|
30 |
-
$this->ipAddress = ahc_get_client_ip_address();
|
31 |
-
if($this->ipAddress == 'UNKNOWN'){
|
32 |
-
$this->ipIsUnknown = true;
|
33 |
-
$this->ipAddress = 'UNKNOWN'.uniqid();
|
34 |
-
} else{
|
35 |
-
$this->ipIsUnknown = false;
|
36 |
-
}
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
}
|
49 |
-
}
|
50 |
-
$this->searchEngine = NULL;
|
51 |
-
$this->keyWords = NULL;
|
52 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
//--------------------------------------------
|
54 |
-
/**
|
55 |
-
* Trace visitor hit
|
56 |
-
*
|
57 |
-
* @return void
|
58 |
-
*/
|
59 |
-
public function traceVisitorHit(){
|
60 |
-
$this->cleanUnwantedRecords();
|
61 |
-
$this->cleanHitsTable();
|
62 |
-
if(!$this->isHitRecorded()){
|
63 |
-
$visitorRecorded = $this->isVisitorRecorded();
|
64 |
-
$this->getBrowser();
|
65 |
-
usleep(10000);
|
66 |
-
if(!empty($this->refererSite)){
|
67 |
-
$this->getSearchEngine();
|
68 |
-
}
|
69 |
-
|
70 |
-
if(!$this->isTodayPreparedInDb()){
|
71 |
-
$this->PrepareForTodayInDb();
|
72 |
-
}
|
73 |
-
|
74 |
-
if(!$visitorRecorded){
|
75 |
-
$this->updateVisitsTime(1, 1);
|
76 |
-
$this->updateVisitors(1, 1);
|
77 |
-
} else{
|
78 |
-
$this->updateVisitsTime(0, 1);
|
79 |
-
$this->updateVisitors(0, 1);
|
80 |
-
}
|
81 |
-
|
82 |
-
if(!empty($this->pageId) && !empty($this->pageTitle) && $this->postType == 'post'){
|
83 |
-
$this->updateTitleTraffic($this->pageId, $this->pageTitle);
|
84 |
-
}
|
85 |
-
|
86 |
-
if(!empty($this->keyWords) && !empty($this->searchEngine)){
|
87 |
-
$this->updateKeywords($this->ipAddress, $this->keyWords, $this->referer, $this->searchEngine, $this->browser);
|
88 |
-
}
|
89 |
-
|
90 |
-
if(!empty($this->refererSite)){
|
91 |
-
$this->updateReferingSites($this->refererSite);
|
92 |
-
}
|
93 |
-
|
94 |
-
if(!empty($this->searchEngine)){
|
95 |
-
$this->updateSearchingVisits($this->searchEngine);
|
96 |
-
}
|
97 |
-
|
98 |
-
$this->updateBrowsers($this->browser);
|
99 |
-
|
100 |
-
if(!$visitorRecorded){
|
101 |
-
$this->updateRecentVisitors($this->ipAddress, $this->referer, $this->searchEngine, $this->browser);
|
102 |
-
}
|
103 |
-
|
104 |
-
$this->recordThisHits();
|
105 |
-
}
|
106 |
-
}
|
107 |
//--------------------------------------------
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
|
|
|
|
121 |
//--------------------------------------------
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
}
|
|
|
|
|
135 |
//--------------------------------------------
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
}
|
161 |
-
}
|
162 |
-
elseif(strpos($this->userAgent, 'Opera Mini') !== false){
|
163 |
-
$this->browser = 6;
|
164 |
-
}
|
165 |
-
elseif(strpos($this->userAgent, 'Opera') !== false){
|
166 |
-
$this->browser = 7;
|
167 |
-
}
|
168 |
-
elseif(strpos($this->userAgent, 'Safari') !== false){
|
169 |
-
$this->browser = 8;
|
170 |
-
}
|
171 |
-
elseif(strpos($this->userAgent, 'iPad') !== false){
|
172 |
-
$this->browser = 9;
|
173 |
-
}
|
174 |
-
elseif(strpos($this->userAgent, 'Android') !== false){
|
175 |
-
$this->browser = 10;
|
176 |
-
}
|
177 |
-
elseif(strpos($this->userAgent, 'AIR') !== false){
|
178 |
-
$this->browser = 11;
|
179 |
-
}
|
180 |
-
elseif(strpos($this->userAgent, 'Fluid') !== false){
|
181 |
-
$this->browser = 12;
|
182 |
-
}
|
183 |
-
elseif(strpos($this->userAgent, 'Maxthon') !== false){
|
184 |
-
$this->browser = 13;
|
185 |
-
}
|
186 |
-
else{
|
187 |
-
$this->browser = 14;
|
188 |
-
}
|
189 |
}
|
|
|
|
|
190 |
//--------------------------------------------
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
}
|
|
|
|
|
212 |
//--------------------------------------------
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
|
|
|
|
|
|
229 |
}
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
* @uses wpdb::get_results()
|
235 |
-
*
|
236 |
-
* @return boolean
|
237 |
-
*/
|
238 |
-
protected function isTodayPreparedInDb(){
|
239 |
-
global $wpdb;
|
240 |
-
$sql = "SELECT COUNT(`vst_id`) AS ct FROM `ahc_visitors` WHERE DATE(`vst_date`) = DATE(NOW())";
|
241 |
-
$result = $wpdb->get_results($sql, OBJECT);
|
242 |
-
if($result !== false){
|
243 |
-
return ((int) $result[0]->ct > 0);
|
244 |
-
}
|
245 |
}
|
|
|
|
|
246 |
//--------------------------------------------
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
|
|
|
|
|
|
262 |
//--------------------------------------------
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
}
|
|
|
278 |
}
|
|
|
|
|
279 |
//--------------------------------------------
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
296 |
}
|
|
|
|
|
297 |
//--------------------------------------------
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
}
|
|
|
|
|
325 |
//--------------------------------------------
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
}
|
|
|
|
|
|
|
|
|
342 |
//--------------------------------------------
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
|
|
|
|
|
|
369 |
}
|
|
|
|
|
370 |
//--------------------------------------------
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
}
|
|
|
|
|
|
|
|
|
390 |
//--------------------------------------------
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
}
|
|
|
|
|
410 |
//--------------------------------------------
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
419 |
*/
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
447 |
}
|
448 |
-
|
449 |
}
|
|
|
|
|
|
|
|
|
450 |
//--------------------------------------------
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
469 |
SET til_hits = til_hits + 1, til_page_title = %s
|
|
|
470 |
WHERE til_id = %d";
|
471 |
-
|
472 |
-
|
473 |
-
|
|
|
|
|
|
|
474 |
VALUES(%s, %s, 1)";
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
|
|
480 |
}
|
|
|
|
|
481 |
//--------------------------------------------
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
498 |
//--------------------------------------------
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
511 |
`srh_id`, `hit_search_words`, `bsr_id`, `hit_date`, `hit_time`)
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
|
|
|
|
|
|
517 |
//--------------------------------------------
|
518 |
}
|
519 |
-
|
|
1 |
<?php
|
2 |
|
3 |
+
class AHCFree_WPHitsCounterPro {
|
4 |
+
|
5 |
+
var $pageId;
|
6 |
+
var $pageTitle;
|
7 |
+
var $postType;
|
8 |
+
var $ipAddress;
|
9 |
+
var $ipIsUnknown;
|
10 |
+
var $userAgent;
|
11 |
+
var $referer;
|
12 |
+
var $refererSite;
|
13 |
+
var $browser;
|
14 |
+
var $searchEngine;
|
15 |
+
var $countryInternetCode;
|
16 |
+
var $countryId;
|
17 |
+
var $keyWords;
|
18 |
+
var $requestUri;
|
19 |
+
|
20 |
+
/**
|
21 |
+
|
22 |
+
* Constructor
|
23 |
+
|
24 |
+
*
|
25 |
+
|
26 |
+
* @param integer $page_id
|
27 |
+
|
28 |
+
* @param string $page_title Optional
|
29 |
+
|
30 |
+
* @param string $post_type Optional
|
31 |
+
|
32 |
+
*/
|
33 |
+
public function __construct($page_id, $page_title = NULL, $post_type = NULL) {
|
34 |
+
|
35 |
+
global $_SERVER;
|
36 |
+
|
37 |
+
$this->ipAddress = ahcfree_get_client_ip_address();
|
38 |
+
|
39 |
+
|
40 |
+
if ($this->ipAddress == 'UNKNOWN') {
|
41 |
+
|
42 |
+
$this->ipIsUnknown = true;
|
43 |
+
|
44 |
+
$this->ipAddress = 'UNKNOWN' . uniqid();
|
45 |
+
} else {
|
46 |
+
|
47 |
+
$this->ipIsUnknown = false;
|
48 |
+
}
|
49 |
+
|
50 |
+
|
51 |
+
|
52 |
+
$this->userAgent = $_SERVER['HTTP_USER_AGENT'];
|
53 |
+
|
54 |
+
$this->pageId = (isset($page_id)) ? $page_id : $_GET['page_id'];
|
55 |
+
|
56 |
+
$this->pageTitle = $page_title;
|
57 |
+
|
58 |
+
$this->postType = $post_type;
|
59 |
|
60 |
+
$this->requestUri = trim($_SERVER['REQUEST_URI'], '/');
|
61 |
|
62 |
+
//$post_permalink = get_the_permalink($this->pageId);
|
63 |
+
//$protocol_arr = array('http://','https://','www.');
|
64 |
+
//$link = str_replace($protocol_arr,'',$post_permalink);
|
65 |
+
//$this->requestUri = trim(str_replace($_SERVER['HTTP_HOST'],'',$link),'/');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
+
if (isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER'])) {
|
68 |
+
|
69 |
+
$hostName = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
|
70 |
+
|
71 |
+
if ($hostName != $_SERVER['SERVER_NAME']) {
|
72 |
+
|
73 |
+
$this->referer = $_SERVER['HTTP_REFERER'];
|
74 |
+
|
75 |
+
$this->refererSite = $hostName;
|
76 |
+
}
|
|
|
|
|
|
|
|
|
77 |
}
|
78 |
+
|
79 |
+
$this->searchEngine = NULL;
|
80 |
+
|
81 |
+
$this->keyWords = NULL;
|
82 |
+
|
83 |
+
$this->countryId = NULL;
|
84 |
+
}
|
85 |
+
|
86 |
//--------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
//--------------------------------------------
|
88 |
+
|
89 |
+
/**
|
90 |
+
|
91 |
+
* Trace visitor hit
|
92 |
+
|
93 |
+
*
|
94 |
+
|
95 |
+
* @return void
|
96 |
+
|
97 |
+
*/
|
98 |
+
public function traceVisitorHit() {
|
99 |
+
|
100 |
+
//$this->cleanUnwantedRecords();
|
101 |
+
|
102 |
+
$this->cleanHitsTable();
|
103 |
+
|
104 |
+
if (!$this->isHitRecorded()) {
|
105 |
+
|
106 |
+
$visitorRecorded = $this->isVisitorRecorded();
|
107 |
+
|
108 |
+
$this->getBrowser();
|
109 |
+
|
110 |
+
usleep(1000);
|
111 |
+
|
112 |
+
if (!empty($this->refererSite)) {
|
113 |
+
|
114 |
+
$this->getSearchEngine();
|
115 |
+
}
|
116 |
+
|
117 |
+
|
118 |
+
/*
|
119 |
+
if (!$this->isTodayPreparedInDb()) {
|
120 |
+
|
121 |
+
$this->PrepareForTodayInDb();
|
122 |
+
}*/
|
123 |
+
|
124 |
+
|
125 |
+
|
126 |
+
if (!$visitorRecorded) {
|
127 |
+
|
128 |
+
$this->updateVisitsTime(1, 1);
|
129 |
+
|
130 |
+
$this->updateVisitors(1, 1);
|
131 |
+
} else {
|
132 |
+
|
133 |
+
$this->updateVisitsTime(0, 1);
|
134 |
+
|
135 |
+
$this->updateVisitors(0, 1);
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
if (!empty($this->pageId) && !empty($this->pageTitle) && ($this->postType == 'post' or $this->postType == 'product' or $this->postType == 'page')) {
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
$this->updateTitleTraffic($this->pageId, $this->pageTitle);
|
144 |
+
}
|
145 |
+
|
146 |
+
|
147 |
+
|
148 |
+
if (!empty($this->keyWords) && !empty($this->searchEngine)) {
|
149 |
+
|
150 |
+
$this->updateKeywords($this->ipAddress, $this->keyWords, $this->referer, $this->searchEngine, $this->browser, $this->countryId);
|
151 |
+
}
|
152 |
+
|
153 |
+
|
154 |
+
|
155 |
+
if (!empty($this->refererSite)) {
|
156 |
+
|
157 |
+
$this->updateReferingSites($this->refererSite);
|
158 |
+
}
|
159 |
+
|
160 |
+
|
161 |
+
|
162 |
+
if (!empty($this->searchEngine)) {
|
163 |
+
|
164 |
+
$this->updateSearchingVisits($this->searchEngine);
|
165 |
+
}
|
166 |
+
|
167 |
+
|
168 |
+
|
169 |
+
if (!empty($this->countryId)) {
|
170 |
+
|
171 |
+
if ($visitorRecorded) {
|
172 |
+
|
173 |
+
$this->updateCountries($this->countryId, 0, 1);
|
174 |
+
} else {
|
175 |
+
|
176 |
+
$this->updateCountries($this->countryId, 1, 1);
|
177 |
}
|
178 |
+
}
|
179 |
+
|
180 |
+
$this->updateBrowsers($this->browser);
|
181 |
+
|
182 |
+
|
183 |
+
|
184 |
+
if (!$visitorRecorded) {
|
185 |
+
|
186 |
+
$this->updateRecentVisitors($this->ipAddress, $this->referer, $this->searchEngine, $this->browser, $this->countryId);
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
|
191 |
+
$this->recordThisHits();
|
192 |
}
|
193 |
+
}
|
194 |
+
|
195 |
//--------------------------------------------
|
196 |
+
|
197 |
+
/**
|
198 |
+
|
199 |
+
* Is visit is already recorded
|
200 |
+
|
201 |
+
*
|
202 |
+
|
203 |
+
* @return boolean
|
204 |
+
|
205 |
+
*/
|
206 |
+
protected function isHitRecorded() {
|
207 |
+
|
208 |
+
global $wpdb;
|
209 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
210 |
+
|
211 |
+
$wpdb->insert(
|
212 |
+
'ahc_online_users',
|
213 |
+
array(
|
214 |
+
'date' => date('Y-m-d H:i:s'),
|
215 |
+
'hit_ip_address' => $this->ipAddress,
|
216 |
+
'hit_page_id' => $this->pageId,
|
217 |
+
)
|
218 |
+
);
|
219 |
+
|
220 |
+
$sql = "SELECT COUNT(`hit_id`) AS ct FROM `ahc_hits` WHERE DATE(`hit_date`) = '". date("Y-m-d") ."' AND `hit_ip_address` = %s AND `hit_page_id` = %s";
|
221 |
+
|
222 |
+
//$sql = "SELECT COUNT(`hit_id`) AS ct FROM `ahc_hits` WHERE DATE(CONVERT_TZ(CONCAT_WS(' ',hit_date,hit_time),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) = DATE(CONVERT_TZ(NOW( ),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) AND `hit_ip_address` = %s AND `hit_page_id` = %s";
|
223 |
+
|
224 |
+
$result = $wpdb->get_results($wpdb->prepare($sql, $this->ipAddress, $this->pageId), OBJECT);
|
225 |
+
|
226 |
+
if ($result !== false) {
|
227 |
+
|
228 |
+
return ((int) $result[0]->ct > 0);
|
229 |
}
|
230 |
+
}
|
231 |
+
|
232 |
//--------------------------------------------
|
233 |
+
|
234 |
+
/**
|
235 |
+
|
236 |
+
* Is visitor is already recorded
|
237 |
+
|
238 |
+
*
|
239 |
+
|
240 |
+
* @return boolean
|
241 |
+
|
242 |
+
*/
|
243 |
+
protected function isVisitorRecorded() {
|
244 |
+
|
245 |
+
global $wpdb;
|
246 |
+
|
247 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
248 |
+
|
249 |
+
$sql = "SELECT COUNT(`hit_id`) AS ct FROM `ahc_hits` WHERE DATE(`hit_date`) = '". date("Y-m-d") ."' AND `hit_ip_address` = %s";
|
250 |
+
|
251 |
+
//$sql = "SELECT COUNT(`hit_id`) AS ct FROM `ahc_hits` WHERE DATE(CONVERT_TZ(CONCAT_WS(' ',hit_date,hit_time),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) = DATE(CONVERT_TZ(NOW( ),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) AND `hit_ip_address` = %s";
|
252 |
+
|
253 |
+
$result = $wpdb->get_results($wpdb->prepare($sql, $this->ipAddress), OBJECT);
|
254 |
+
if ($result !== false) {
|
255 |
+
|
256 |
+
return ((int) $result[0]->ct > 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
}
|
258 |
+
}
|
259 |
+
|
260 |
//--------------------------------------------
|
261 |
+
|
262 |
+
/**
|
263 |
+
|
264 |
+
* Detect client browser
|
265 |
+
|
266 |
+
*
|
267 |
+
|
268 |
+
* @return void
|
269 |
+
|
270 |
+
*/
|
271 |
+
protected function getBrowser() {
|
272 |
+
|
273 |
+
if (strpos($this->userAgent, 'MSIE') !== false) {
|
274 |
+
|
275 |
+
$this->browser = 1;
|
276 |
+
} elseif (strpos($this->userAgent, 'Trident') !== false) {
|
277 |
+
|
278 |
+
$this->browser = 1;
|
279 |
+
} elseif (strpos($this->userAgent, 'Gecko') !== false) {
|
280 |
+
|
281 |
+
if (strpos($this->userAgent, 'Firefox') !== false) {
|
282 |
+
|
283 |
+
$this->browser = 2;
|
284 |
+
} elseif (strpos($this->userAgent, 'Netscape') !== false) {
|
285 |
+
|
286 |
+
$this->browser = 3;
|
287 |
+
} elseif (strpos($this->userAgent, 'Chrome') !== false) {
|
288 |
+
|
289 |
+
$this->browser = 4;
|
290 |
+
} else {
|
291 |
+
|
292 |
+
$this->browser = 5;
|
293 |
+
}
|
294 |
+
} elseif (strpos($this->userAgent, 'Opera Mini') !== false) {
|
295 |
+
|
296 |
+
$this->browser = 6;
|
297 |
+
} elseif (strpos($this->userAgent, 'Opera') !== false) {
|
298 |
+
|
299 |
+
$this->browser = 7;
|
300 |
+
} elseif (strpos($this->userAgent, 'Safari') !== false) {
|
301 |
+
|
302 |
+
$this->browser = 8;
|
303 |
+
} elseif (strpos($this->userAgent, 'iPad') !== false) {
|
304 |
+
|
305 |
+
$this->browser = 9;
|
306 |
+
} elseif (strpos($this->userAgent, 'Android') !== false) {
|
307 |
+
|
308 |
+
$this->browser = 10;
|
309 |
+
} elseif (strpos($this->userAgent, 'AIR') !== false) {
|
310 |
+
|
311 |
+
$this->browser = 11;
|
312 |
+
} elseif (strpos($this->userAgent, 'Fluid') !== false) {
|
313 |
+
|
314 |
+
$this->browser = 12;
|
315 |
+
} elseif (strpos($this->userAgent, 'Maxthon') !== false) {
|
316 |
+
|
317 |
+
$this->browser = 13;
|
318 |
+
} else {
|
319 |
+
|
320 |
+
$this->browser = 14;
|
321 |
}
|
322 |
+
}
|
323 |
+
|
324 |
//--------------------------------------------
|
325 |
+
|
326 |
+
/**
|
327 |
+
|
328 |
+
* Detect country internet code
|
329 |
+
|
330 |
+
*
|
331 |
+
|
332 |
+
* @return void
|
333 |
+
|
334 |
+
*/
|
335 |
+
protected function getCountryInternetCode() {
|
336 |
+
|
337 |
+
if (!$this->ipIsUnknown) {
|
338 |
+
|
339 |
+
$gi = geoip_open(AHCFREE_PLUGIN_ROOT_DIR . AHCFREE_DS . "geoip" . AHCFREE_DS . "data" . AHCFREE_DS . "GeoIP.dat", GEOIP_STANDARD);
|
340 |
+
|
341 |
+
$this->countryInternetCode = geoip_country_code_by_addr($gi, $this->ipAddress);
|
342 |
+
|
343 |
+
geoip_close($gi);
|
344 |
}
|
345 |
+
|
346 |
+
if (empty($this->countryInternetCode)) {
|
347 |
+
|
348 |
+
$this->countryInternetCode = 'XX';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
349 |
}
|
350 |
+
}
|
351 |
+
|
352 |
//--------------------------------------------
|
353 |
+
|
354 |
+
/**
|
355 |
+
|
356 |
+
* Detect country ID
|
357 |
+
|
358 |
+
*
|
359 |
+
|
360 |
+
* @uses wpdb::prepare()
|
361 |
+
|
362 |
+
* @uses wpdb::get_results()
|
363 |
+
|
364 |
+
*
|
365 |
+
|
366 |
+
* @return void
|
367 |
+
|
368 |
+
*/
|
369 |
+
|
370 |
+
|
371 |
//--------------------------------------------
|
372 |
+
|
373 |
+
/**
|
374 |
+
|
375 |
+
* Detect search engine
|
376 |
+
|
377 |
+
*
|
378 |
+
|
379 |
+
* @uses wpdb::prepare()
|
380 |
+
|
381 |
+
* @uses wpdb::get_results()
|
382 |
+
|
383 |
+
*
|
384 |
+
|
385 |
+
* @return void
|
386 |
+
|
387 |
+
*/
|
388 |
+
protected function getSearchEngine() {
|
389 |
+
|
390 |
+
global $wpdb;
|
391 |
+
|
392 |
+
$sql = "SELECT `srh_id`, `srh_query_parameter`, `srh_identifier` FROM `ahc_search_engines`";
|
393 |
+
|
394 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
395 |
+
|
396 |
+
if ($results !== false) {
|
397 |
+
|
398 |
+
foreach ($results as $s) {
|
399 |
+
|
400 |
+
if (strpos($this->referer, $s->srh_identifier . '.') !== false) {
|
401 |
+
|
402 |
+
$this->searchEngine = $s->srh_id;
|
403 |
+
|
404 |
+
$this->getKeyWords($s->srh_query_parameter);
|
405 |
}
|
406 |
+
}
|
407 |
}
|
408 |
+
}
|
409 |
+
|
410 |
//--------------------------------------------
|
411 |
+
|
412 |
+
/**
|
413 |
+
|
414 |
+
* Detect search engine
|
415 |
+
|
416 |
+
*
|
417 |
+
|
418 |
+
* @uses wpdb::prepare()
|
419 |
+
|
420 |
+
* @uses wpdb::get_results()
|
421 |
+
|
422 |
+
*
|
423 |
+
|
424 |
+
* @return void
|
425 |
+
|
426 |
+
*/
|
427 |
+
protected function getKeyWords($query_param) {
|
428 |
+
|
429 |
+
$query = parse_url($this->referer, PHP_URL_QUERY);
|
430 |
+
|
431 |
+
$query = rawurldecode($query);
|
432 |
+
|
433 |
+
$arr = array();
|
434 |
+
|
435 |
+
parse_str($query, $arr);
|
436 |
+
|
437 |
+
if (isset($arr[$query_param])) {
|
438 |
+
|
439 |
+
$this->keyWords = $arr[$query_param];
|
440 |
}
|
441 |
+
}
|
442 |
+
|
443 |
//--------------------------------------------
|
444 |
+
|
445 |
+
/**
|
446 |
+
|
447 |
+
* Is there a record prepared for today's visits
|
448 |
+
|
449 |
+
*
|
450 |
+
|
451 |
+
* @uses wpdb::get_results()
|
452 |
+
|
453 |
+
*
|
454 |
+
|
455 |
+
* @return boolean
|
456 |
+
|
457 |
+
*/
|
458 |
+
protected function isTodayPreparedInDb() {
|
459 |
+
|
460 |
+
global $wpdb;
|
461 |
+
|
462 |
+
$del_sql = "DELETE v1 FROM ahc_visitors v1, ahc_visitors v2 WHERE v1.`vst_id` > v2.`vst_id` AND v1.`vst_date` = v2.`vst_date`";
|
463 |
+
|
464 |
+
//$del_sql = "DELETE v1 FROM ahc_visitors v1, ahc_visitors v2 WHERE v1.`vst_id` > v2.`vst_id` AND CONVERT_TZ(v1.vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') = CONVERT_TZ(v2.vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') ";
|
465 |
+
|
466 |
+
$del_result = $wpdb->get_results($del_sql, OBJECT);
|
467 |
+
|
468 |
+
|
469 |
+
$sql = "SELECT COUNT(`vst_id`) AS ct FROM `ahc_visitors` WHERE DATE(`vst_date`) = '".date("Y-m-d")."'";
|
470 |
+
|
471 |
+
//$sql = "SELECT COUNT(`vst_id`) AS ct FROM `ahc_visitors` WHERE DATE(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) = DATE(CONVERT_TZ(NOW( ),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "'))";
|
472 |
+
|
473 |
+
$result = $wpdb->get_results($sql, OBJECT);
|
474 |
+
|
475 |
+
if ($result !== false) {
|
476 |
+
|
477 |
+
return ((int) $result[0]->ct > 0);
|
478 |
}
|
479 |
+
}
|
480 |
+
|
481 |
//--------------------------------------------
|
482 |
+
|
483 |
+
/**
|
484 |
+
|
485 |
+
* Prepared a record for today's visits
|
486 |
+
|
487 |
+
*
|
488 |
+
|
489 |
+
* @uses wpdb::query()
|
490 |
+
|
491 |
+
*
|
492 |
+
|
493 |
+
* @return boolean
|
494 |
+
|
495 |
+
*/
|
496 |
+
protected function PrepareForTodayInDb() {
|
497 |
+
|
498 |
+
global $wpdb;
|
499 |
+
|
500 |
+
$sql = "INSERT INTO `ahc_visitors` (`vst_date`, `vst_visitors`, `vst_visits`) VALUES ('".date("Y-m-d H:i:s")."', 0, 0)";
|
501 |
+
|
502 |
+
if ($wpdb->query($sql) !== false) {
|
503 |
+
|
504 |
+
return true;
|
505 |
}
|
506 |
+
|
507 |
+
return false;
|
508 |
+
}
|
509 |
+
|
510 |
//--------------------------------------------
|
511 |
+
|
512 |
+
/**
|
513 |
+
|
514 |
+
* Clean daily hits table
|
515 |
+
|
516 |
+
*
|
517 |
+
|
518 |
+
* @uses wpdb::query()
|
519 |
+
|
520 |
+
*
|
521 |
+
|
522 |
+
* @return boolean
|
523 |
+
|
524 |
+
*/
|
525 |
+
protected function cleanHitsTable() {
|
526 |
+
|
527 |
+
global $wpdb;
|
528 |
+
|
529 |
+
$sql = "DELETE FROM ahc_online_users WHERE DATE(`date`) <> '".date("Y-m-d")."'";
|
530 |
+
$wpdb->query($sql);
|
531 |
+
|
532 |
+
$sql = "DELETE FROM `ahc_hits` WHERE DATE(`hit_date`) <> '".date("Y-m-d")."'";
|
533 |
+
|
534 |
+
if ($wpdb->query($sql) !== false) {
|
535 |
+
|
536 |
+
return true;
|
537 |
+
} else {
|
538 |
+
|
539 |
+
return false;
|
540 |
}
|
541 |
+
}
|
542 |
+
|
543 |
//--------------------------------------------
|
544 |
+
|
545 |
+
/**
|
546 |
+
|
547 |
+
* Update browser visits
|
548 |
+
|
549 |
+
*
|
550 |
+
|
551 |
+
* @uses wpdb::prepare()
|
552 |
+
|
553 |
+
* @uses wpdb::query()
|
554 |
+
|
555 |
+
*
|
556 |
+
|
557 |
+
* @param integer $bsr_id
|
558 |
+
|
559 |
+
* @return boolean
|
560 |
+
|
561 |
+
*/
|
562 |
+
protected function updateBrowsers($bsr_id) {
|
563 |
+
|
564 |
+
global $wpdb;
|
565 |
+
|
566 |
+
$sql = "UPDATE `ahc_browsers` SET bsr_visits = bsr_visits + 1 WHERE bsr_id = %d";
|
567 |
+
|
568 |
+
if ($wpdb->query($wpdb->prepare($sql, $bsr_id)) !== false) {
|
569 |
+
|
570 |
+
return true;
|
571 |
}
|
572 |
+
|
573 |
+
return false;
|
574 |
+
}
|
575 |
+
|
576 |
//--------------------------------------------
|
577 |
+
|
578 |
+
/**
|
579 |
+
|
580 |
+
* Update country visits
|
581 |
+
|
582 |
+
*
|
583 |
+
|
584 |
+
* @uses wpdb::prepare()
|
585 |
+
|
586 |
+
* @uses wpdb::query()
|
587 |
+
|
588 |
+
*
|
589 |
+
|
590 |
+
* @param integer $ctr_id
|
591 |
+
|
592 |
+
* @param integer $visitors Optional
|
593 |
+
|
594 |
+
* @param integer $visits Optional
|
595 |
+
|
596 |
+
* @return boolean
|
597 |
+
|
598 |
+
*/
|
599 |
+
protected function updateCountries($ctr_id, $visitors = 0, $visits = 0) {
|
600 |
+
|
601 |
+
global $wpdb;
|
602 |
+
|
603 |
+
$sql = "UPDATE `ahc_countries` SET ctr_visitors = ctr_visitors + %d, ctr_visits = ctr_visits + %d WHERE ctr_id = %d";
|
604 |
+
|
605 |
+
return ($wpdb->query($wpdb->prepare($sql, $visitors, $visits, $ctr_id)) !== false);
|
606 |
+
}
|
607 |
+
|
608 |
+
//--------------------------------------------
|
609 |
+
|
610 |
+
/**
|
611 |
+
|
612 |
+
* Update visits sum order by search engine
|
613 |
+
|
614 |
+
*
|
615 |
+
|
616 |
+
* @uses wpdb::prepare()
|
617 |
+
|
618 |
+
* @uses wpdb::get_results()
|
619 |
+
|
620 |
+
* @uses wpdb::query()
|
621 |
+
|
622 |
+
*
|
623 |
+
|
624 |
+
* @param integer $srh_id
|
625 |
+
|
626 |
+
* @return boolean
|
627 |
+
|
628 |
+
*/
|
629 |
+
protected function updateSearchingVisits($srh_id) {
|
630 |
+
|
631 |
+
global $wpdb;
|
632 |
+
|
633 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
634 |
+
|
635 |
+
$sql = "SELECT vtsh_id FROM `ahc_searching_visits` WHERE srh_id = %d AND DATE(vtsh_date) = '".date("Y-m-d")."'";
|
636 |
+
//$sql = "SELECT vtsh_id FROM `ahc_searching_visits` WHERE srh_id = %d AND DATE(CONVERT_TZ(vtsh_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) = DATE(CONVERT_TZ(NOW( ),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "'))";
|
637 |
+
|
638 |
+
$result = $wpdb->get_results($wpdb->prepare($sql, $srh_id), OBJECT);
|
639 |
+
|
640 |
+
if ($result !== false) {
|
641 |
+
|
642 |
+
if ($wpdb->num_rows > 0) {
|
643 |
+
|
644 |
+
$sql2 = "UPDATE `ahc_searching_visits` SET vtsh_visits = vtsh_visits + 1 WHERE vtsh_id = %d";
|
645 |
+
|
646 |
+
return ($wpdb->query($wpdb->prepare($sql2, $result[0]->vtsh_id)) !== false);
|
647 |
+
} else {
|
648 |
+
|
649 |
+
$sql2 = "INSERT INTO `ahc_searching_visits` (srh_id, vtsh_date, vtsh_visits)
|
650 |
+
|
651 |
+
VALUES (%d, %s, 1)";
|
652 |
+
|
653 |
+
return ($wpdb->query($wpdb->prepare($sql2, $srh_id, date("Y-m-d H:i:s"))) !== false);
|
654 |
+
}
|
655 |
+
} else {
|
656 |
+
|
657 |
+
return false;
|
658 |
}
|
659 |
+
}
|
660 |
+
|
661 |
//--------------------------------------------
|
662 |
+
|
663 |
+
/**
|
664 |
+
|
665 |
+
* Update visitors count
|
666 |
+
|
667 |
+
*
|
668 |
+
|
669 |
+
* @uses wpdb::prepare()
|
670 |
+
|
671 |
+
* @uses wpdb::query()
|
672 |
+
|
673 |
+
*
|
674 |
+
|
675 |
+
* @param integer $visitors Optional
|
676 |
+
|
677 |
+
* @param integer $visits Optional
|
678 |
+
|
679 |
+
* @return boolean
|
680 |
+
|
681 |
+
*/
|
682 |
+
protected function updateVisitors($visitors = 0, $visits = 0) {
|
683 |
+
|
684 |
+
global $wpdb;
|
685 |
+
|
686 |
+
|
687 |
+
$sql = "INSERT INTO `ahc_daily_visitors_stats` (vst_date, vst_visitors, vst_visits) values(%s, %d, %d )";
|
688 |
+
|
689 |
+
$wpdb->query($wpdb->prepare($sql, date("Y-m-d H:i:s"), $visitors, $visits));
|
690 |
+
|
691 |
+
$sql = "INSERT INTO `ahc_visitors` (vst_date, vst_visitors, vst_visits) values(%s, %d, %d )";
|
692 |
+
//$sql = "UPDATE `ahc_visitors` SET vst_visitors = vst_visitors + %d, vst_visits = vst_visits + %d WHERE DATE(vst_date) = DATE(NOW())";
|
693 |
+
|
694 |
+
return ($wpdb->query($wpdb->prepare($sql, date("Y-m-d H:i:s"), $visitors, $visits)) !== false);
|
695 |
+
}
|
696 |
+
|
697 |
+
//--------------------------------------------
|
698 |
+
|
699 |
+
/**
|
700 |
+
|
701 |
+
* Update referring sites visits table
|
702 |
+
|
703 |
+
*
|
704 |
+
|
705 |
+
* @uses wpdb::prepare()
|
706 |
+
|
707 |
+
* @uses wpdb::query()
|
708 |
+
|
709 |
+
* @uses wpdb::get_results()
|
710 |
+
|
711 |
+
*
|
712 |
+
|
713 |
+
* @param string $rfr_site_name. referring site name
|
714 |
+
|
715 |
+
* @return boolean
|
716 |
+
|
717 |
+
*/
|
718 |
+
protected function updateReferingSites($rfr_site_name) {
|
719 |
+
|
720 |
+
global $wpdb;
|
721 |
+
|
722 |
+
$sql = "SELECT rfr_id FROM `ahc_refering_sites` where rfr_site_name = %s";
|
723 |
+
|
724 |
+
$result = $wpdb->get_results($wpdb->prepare($sql, $rfr_site_name), OBJECT);
|
725 |
+
|
726 |
+
if ($result !== false) {
|
727 |
+
|
728 |
+
if (!empty($result)) {
|
729 |
+
|
730 |
+
$sql2 = "UPDATE `ahc_refering_sites` SET rfr_visits = rfr_visits + 1 WHERE rfr_id = %d";
|
731 |
+
|
732 |
+
return ($wpdb->query($wpdb->prepare($sql2, $result[0]->rfr_id)) !== false);
|
733 |
+
} else {
|
734 |
+
|
735 |
+
$sql2 = "INSERT INTO `ahc_refering_sites` (rfr_site_name, rfr_visits)
|
736 |
+
|
737 |
+
VALUES(%s, 1)";
|
738 |
+
|
739 |
+
return ($wpdb->query($wpdb->prepare($sql2, $rfr_site_name)) !== false);
|
740 |
+
}
|
741 |
+
} else {
|
742 |
+
|
743 |
+
return false;
|
744 |
+
}
|
745 |
+
}
|
746 |
+
|
747 |
+
//--------------------------------------------
|
748 |
+
|
749 |
+
/**
|
750 |
+
|
751 |
+
* Update recent visitors table
|
752 |
+
|
753 |
+
*
|
754 |
+
|
755 |
+
* @uses wpdb::prepare()
|
756 |
+
|
757 |
+
* @uses wpdb::query()
|
758 |
+
|
759 |
+
*
|
760 |
+
|
761 |
+
* @param string $vtr_ip_address. IP address
|
762 |
+
|
763 |
+
* @param string $vtr_referer Optional. Referring site name
|
764 |
+
|
765 |
+
* @param integer $srh_id Optional. Search engine ID
|
766 |
+
|
767 |
+
* @param integer $bsr_id Optional. Browser ID
|
768 |
+
|
769 |
+
* @param integer $ctr_id Optional. Country ID
|
770 |
+
|
771 |
+
* @return boolean
|
772 |
+
|
773 |
+
*/
|
774 |
+
protected function updateRecentVisitors($vtr_ip_address, $vtr_referer = '', $srh_id = NULL, $bsr_id = NULL, $ctr_id = NULL) {
|
775 |
+
|
776 |
+
global $wpdb;
|
777 |
+
|
778 |
+
|
779 |
+
|
780 |
+
|
781 |
+
/* $ip_data = (ahcfree_advanced_get_link("http://ip-api.com/json/".$vtr_ip_address));
|
782 |
+
$ip_data = json_decode($ip_data['body']);
|
783 |
+
|
784 |
+
if($ip_data->city != '')
|
785 |
+
{
|
786 |
+
|
787 |
+
$ahc_city = $ip_data->city;
|
788 |
+
$ahc_region = $ip_data->regionName;
|
789 |
+
}
|
790 |
+
|
791 |
+
if(empty($ip_data->city) or empty($ip_data->regionName))
|
792 |
+
{
|
793 |
+
$ip_data = (ahcfree_advanced_get_link("http://api.db-ip.com/v2/c425dbfb764da5017d283d8a2d53360be0869a4b/".$vtr_ip_address));
|
794 |
+
$ip_data = json_decode($ip_data['body']);
|
795 |
+
|
796 |
+
$ahc_city = $ip_data->city;
|
797 |
+
$ahc_region = $ip_data->stateProv;
|
798 |
+
}
|
799 |
+
|
800 |
*/
|
801 |
+
|
802 |
+
|
803 |
+
|
804 |
+
$ip_data = (ahcfree_advanced_get_link("http://www.geoplugin.net/json.gp?ip=" . $vtr_ip_address));
|
805 |
+
$ip_data = json_decode($ip_data['body']);
|
806 |
+
|
807 |
+
|
808 |
+
if ($ip_data->geoplugin_city != '') {
|
809 |
+
|
810 |
+
$ahc_city = $ip_data->geoplugin_countryName;
|
811 |
+
$ahc_region = $ip_data->geoplugin_city;
|
812 |
+
}
|
813 |
+
|
814 |
+
if (empty($ip_data->geoplugin_city) or empty($ip_data->geoplugin_city)) {
|
815 |
+
$ip_data = (ahcfree_advanced_get_link("http://ip-api.com/json/" . $vtr_ip_address));
|
816 |
+
$ip_data = json_decode($ip_data['body']);
|
817 |
+
|
818 |
+
$ahc_city = $ip_data->city;
|
819 |
+
$ahc_region = $ip_data->regionName;
|
820 |
+
}
|
821 |
+
|
822 |
+
|
823 |
+
$sql = "INSERT INTO `ahc_recent_visitors` (vtr_ip_address, vtr_referer, srh_id, bsr_id, ctr_id, ahc_city, ahc_region, vtr_date, vtr_time) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)";
|
824 |
+
|
825 |
+
|
826 |
+
|
827 |
+
return ($wpdb->query($wpdb->prepare($sql, $vtr_ip_address, $vtr_referer, $srh_id, $bsr_id, $ctr_id, $ahc_city, $ahc_region, date("Y-m-d"), date("H:i:s") )) !== false);
|
828 |
+
}
|
829 |
+
|
830 |
+
//--------------------------------------------
|
831 |
+
|
832 |
+
/**
|
833 |
+
|
834 |
+
* Update key words table
|
835 |
+
|
836 |
+
*
|
837 |
+
|
838 |
+
* @uses wpdb::prepare()
|
839 |
+
|
840 |
+
* @uses wpdb::query()
|
841 |
+
|
842 |
+
*
|
843 |
+
|
844 |
+
* @param string $vtr_ip_address. IP address
|
845 |
+
|
846 |
+
* @param string $kwd_keywords. Key word
|
847 |
+
|
848 |
+
* @param string $kwd_referer. Referring site name.
|
849 |
+
|
850 |
+
* @param integer $srh_id. Search engine ID
|
851 |
+
|
852 |
+
* @param integer $bsr_id. Browser ID
|
853 |
+
|
854 |
+
* @param integer $ctr_id Optional. Country ID
|
855 |
+
|
856 |
+
* @return boolean
|
857 |
+
|
858 |
+
*/
|
859 |
+
protected function updateKeywords($kwd_ip_address, $kwd_keywords, $kwd_referer, $srh_id, $bsr_id, $ctr_id = NULL) {
|
860 |
+
|
861 |
+
global $wpdb;
|
862 |
+
|
863 |
+
$sql = "INSERT INTO `ahc_keywords` (kwd_ip_address, kwd_keywords, kwd_referer, srh_id, ctr_id, bsr_id, kwd_date, kwd_time)
|
864 |
+
|
865 |
+
VALUES (%s, %s, %s, %d, %d, %d, %s, %s)";
|
866 |
+
|
867 |
+
return ($wpdb->query($wpdb->prepare($sql, $kwd_ip_address, $kwd_keywords, $kwd_referer, $srh_id, $ctr_id, $bsr_id, date("Y-m-d"), date("H:i:s"))) !== false);
|
868 |
+
}
|
869 |
+
|
870 |
+
//--------------------------------------------
|
871 |
+
|
872 |
+
/**
|
873 |
+
|
874 |
+
* Clean unwanted records. Only keeping a limit of fresh records. Limit is set by AHC_RECENT_VISITORS_LIMIT
|
875 |
+
|
876 |
+
*
|
877 |
+
|
878 |
+
* @uses wpdb::prepare()
|
879 |
+
|
880 |
+
* @uses wpdb::get_results()
|
881 |
+
|
882 |
+
* @uses wpdb::query()
|
883 |
+
|
884 |
+
*
|
885 |
+
|
886 |
+
* @return boolean
|
887 |
+
|
888 |
+
*/
|
889 |
+
protected function cleanUnwantedRecords() {
|
890 |
+
|
891 |
+
global $wpdb;
|
892 |
+
|
893 |
+
$sql11 = "SELECT vtr_id FROM `ahc_recent_visitors` ORDER BY vtr_id LIMIT %d";
|
894 |
+
|
895 |
+
$result = $wpdb->get_results($wpdb->prepare($sql11, AHC_RECENT_VISITORS_LIMIT), OBJECT);
|
896 |
+
|
897 |
+
if ($result !== false) {
|
898 |
+
|
899 |
+
$ids1 = array();
|
900 |
+
|
901 |
+
$length = count($result);
|
902 |
+
|
903 |
+
foreach ($result as $r) {
|
904 |
+
|
905 |
+
$ids1[] = $r->vtr_id;
|
906 |
+
}
|
907 |
+
|
908 |
+
$ids1 = implode(',', $ids1);
|
909 |
+
|
910 |
+
$sql12 = "DELETE FROM `ahc_recent_visitors`" . ((!empty($ids1)) ? " WHERE vtr_id NOT IN (" . $ids1 . ")" : "");
|
911 |
+
|
912 |
+
|
913 |
+
|
914 |
+
$sql21 = "SELECT kwd_id FROM `ahc_keywords` ORDER BY kwd_id LIMIT %d";
|
915 |
+
|
916 |
+
$result2 = $wpdb->get_results($wpdb->prepare($sql21, AHCFREE_RECENT_KEYWORDS_LIMIT), OBJECT);
|
917 |
+
|
918 |
+
if ($result2 !== false) {
|
919 |
+
|
920 |
+
$ids2 = array();
|
921 |
+
|
922 |
+
foreach ($result2 as $r) {
|
923 |
+
|
924 |
+
$ids2[] = $r->kwd_id;
|
925 |
+
}
|
926 |
+
|
927 |
+
$ids2 = implode(',', $ids2);
|
928 |
+
|
929 |
+
$sql22 = "DELETE FROM `ahc_keywords`" . ((!empty($ids2)) ? " WHERE kwd_id NOT IN (" . $ids2 . ")" : "");
|
930 |
+
|
931 |
+
|
932 |
+
|
933 |
+
if ($wpdb->query($sql12) !== false) {
|
934 |
+
|
935 |
+
return ($wpdb->query($sql22) !== false);
|
936 |
}
|
937 |
+
}
|
938 |
}
|
939 |
+
|
940 |
+
return false;
|
941 |
+
}
|
942 |
+
|
943 |
//--------------------------------------------
|
944 |
+
|
945 |
+
/**
|
946 |
+
|
947 |
+
* Update traffic by title table
|
948 |
+
|
949 |
+
*
|
950 |
+
|
951 |
+
* @uses wpdb::prepare()
|
952 |
+
|
953 |
+
* @uses wpdb::get_results()
|
954 |
+
|
955 |
+
* @uses wpdb::query()
|
956 |
+
|
957 |
+
*
|
958 |
+
|
959 |
+
* @param integer $til_page_id
|
960 |
+
|
961 |
+
* @param string $til_page_title
|
962 |
+
|
963 |
+
* @return boolean
|
964 |
+
|
965 |
+
*/
|
966 |
+
protected function updateTitleTraffic($til_page_id, $til_page_title) {
|
967 |
+
|
968 |
+
global $wpdb;
|
969 |
+
|
970 |
+
$sql = "SELECT til_id FROM `ahc_title_traffic` where til_page_id = %s";
|
971 |
+
|
972 |
+
$result = $wpdb->get_results($wpdb->prepare($sql, $til_page_id), OBJECT);
|
973 |
+
|
974 |
+
if ($result !== false) {
|
975 |
+
|
976 |
+
if (!empty($result)) {
|
977 |
+
|
978 |
+
$sql2 = "UPDATE `ahc_title_traffic`
|
979 |
+
|
980 |
SET til_hits = til_hits + 1, til_page_title = %s
|
981 |
+
|
982 |
WHERE til_id = %d";
|
983 |
+
|
984 |
+
return ($wpdb->query($wpdb->prepare($sql2, $til_page_title, $result[0]->til_id)) !== false);
|
985 |
+
} else {
|
986 |
+
|
987 |
+
$sql2 = "INSERT INTO `ahc_title_traffic` (til_page_id, til_page_title, til_hits)
|
988 |
+
|
989 |
VALUES(%s, %s, 1)";
|
990 |
+
|
991 |
+
return ($wpdb->query($wpdb->prepare($sql2, $til_page_id, $til_page_title)) !== false);
|
992 |
+
}
|
993 |
+
} else {
|
994 |
+
|
995 |
+
return false;
|
996 |
}
|
997 |
+
}
|
998 |
+
|
999 |
//--------------------------------------------
|
1000 |
+
|
1001 |
+
/**
|
1002 |
+
|
1003 |
+
* Update visitor's & visits' times table
|
1004 |
+
|
1005 |
+
*
|
1006 |
+
|
1007 |
+
* @uses wpdb::prepare()
|
1008 |
+
|
1009 |
+
* @uses wpdb::query()
|
1010 |
+
|
1011 |
+
*
|
1012 |
+
|
1013 |
+
* @param integer $visitors Optional
|
1014 |
+
|
1015 |
+
* @param integer $visits Optional
|
1016 |
+
|
1017 |
+
* @return boolean
|
1018 |
+
|
1019 |
+
*/
|
1020 |
+
protected function updateVisitsTime($visitors = 0, $visits = 0) {
|
1021 |
+
|
1022 |
+
global $wpdb;
|
1023 |
+
$time = date('H:i:s');
|
1024 |
+
$sql = "UPDATE `ahc_visits_time` SET vtm_visitors = vtm_visitors + %d, vtm_visits = vtm_visits + %d
|
1025 |
+
|
1026 |
+
WHERE TIME(vtm_time_from) <= '$time' AND TIME(vtm_time_to) >= '$time'";
|
1027 |
+
$query = $wpdb->prepare($sql, $visitors, $visits);
|
1028 |
+
$result = ($wpdb->query($query) !== false);
|
1029 |
+
|
1030 |
+
$sql = "UPDATE `ahc_visits_time` SET vtm_visitors = 1
|
1031 |
+
|
1032 |
+
WHERE vtm_visitors = 0 AND TIME(vtm_time_from) <= '$time' AND TIME(vtm_time_to) >= '$time'";
|
1033 |
+
$query = $wpdb->query($sql);
|
1034 |
+
|
1035 |
+
$sql = "UPDATE `ahc_visits_time` SET vtm_visits = 1
|
1036 |
+
|
1037 |
+
WHERE vtm_visits = 0 AND TIME(vtm_time_from) <= '$time' AND TIME(vtm_time_to) >= '$time'";
|
1038 |
+
$query = $wpdb->query($sql);
|
1039 |
+
|
1040 |
+
return $result;
|
1041 |
+
}
|
1042 |
+
|
1043 |
//--------------------------------------------
|
1044 |
+
|
1045 |
+
/**
|
1046 |
+
|
1047 |
+
* Record (insert) the visit
|
1048 |
+
|
1049 |
+
*
|
1050 |
+
|
1051 |
+
* @uses wpdb::prepare()
|
1052 |
+
|
1053 |
+
* @uses wpdb::query()
|
1054 |
+
|
1055 |
+
*
|
1056 |
+
|
1057 |
+
* @return boolean
|
1058 |
+
|
1059 |
+
*/
|
1060 |
+
protected function recordThisHits() {
|
1061 |
+
|
1062 |
+
global $wpdb;
|
1063 |
+
|
1064 |
+
$sql = "INSERT INTO `ahc_hits`
|
1065 |
+
|
1066 |
+
(`hit_ip_address`, `hit_user_agent`, `hit_request_uri`, `hit_page_id`, `hit_page_title`, `ctr_id`, `hit_referer`, `hit_referer_site`,
|
1067 |
+
|
1068 |
`srh_id`, `hit_search_words`, `bsr_id`, `hit_date`, `hit_time`)
|
1069 |
+
|
1070 |
+
VALUES (%s, %s, %s, %s, %s, %d, %s, %s, %d, %s, %d, %s, %s)";
|
1071 |
+
|
1072 |
+
$result = $wpdb->query($wpdb->prepare($sql, $this->ipAddress, $this->userAgent, $this->requestUri, $this->pageId, $this->pageTitle, $this->countryId, $this->referer, $this->refererSite, $this->searchEngine, $this->keyWords, $this->browser, date("Y-m-d"), date("H:i:s") ));
|
1073 |
+
|
1074 |
+
return ($result !== false);
|
1075 |
+
}
|
1076 |
+
|
1077 |
//--------------------------------------------
|
1078 |
}
|
1079 |
+
|
1080 |
+
?>
|
ahc_about.php
ADDED
File without changes
|
ahc_help.php
ADDED
File without changes
|
ahc_settings.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
0 |
i{
|
1 |
}
|
|
|
2 |
if (ahcfree_savesettings()) {
|
|
|
3 |
<h1><img width="40px" src="<?php echo plugins_url('/images/logo.png', AHCFREE_PLUGIN_MAIN_FILE) ?>"> Visitor Traffic Real Time Statistics <a title="change settings" href="admin.php?page=ahc_hits_counter_settings"><img src="<?php echo plugins_url('/images/settings.jpg', AHCFREE_PLUGIN_MAIN_FILE) ?>" /></a></h1><br />
|
4 |
<div class="panel">
|
5 |
<h2 style="height:35px !important; font-size:13px !important">Settings</h2>
|
6 |
<option value="<?php echo $value; ?>" <?php echo ( $value == $custom_timezone_offset ) ? 'selected' : ''; ?>><?php echo $value; ?></option>
|
7 |
global $wp_roles;
|
8 |
if ( !isset( $wp_roles ) ) $wp_roles = new WP_Roles();
|
9 |
$available_roles_names = $wp_roles->get_names();//we get all roles names
|
10 |
$available_roles_capable = array();
|
11 |
foreach ($available_roles_names as $role_key => $role_name) { //we iterate all the names
|
12 |
$role_object = get_role( $role_key );//we get the Role Object
|
13 |
$array_of_capabilities = $role_object->capabilities;//we get the array of capabilities for this role
|
14 |
if($array_of_capabilities['update_plugins'] == 1 || $array_of_capabilities['manage_links'] == 1 || $array_of_capabilities['manage_sites'] == 1 ){ //we check if the upload_files capability is present, and if its present check if its 0 (FALSE in Php)
|
15 |
$available_roles_capable[$role_key] = $role_name; //we populate the array of capable roles
|
16 |
}
|
17 |
}
|
18 |
|
19 |
select: \'#ahcUserRoles\'
|
|
|
|
1 |
+
|
2 |
i{
|
3 |
}
|
4 |
+
if (!empty($_POST['save'])) {
|
5 |
if (ahcfree_savesettings()) {
|
6 |
+
}
|
7 |
<h1><img width="40px" src="<?php echo plugins_url('/images/logo.png', AHCFREE_PLUGIN_MAIN_FILE) ?>"> Visitor Traffic Real Time Statistics <a title="change settings" href="admin.php?page=ahc_hits_counter_settings"><img src="<?php echo plugins_url('/images/settings.jpg', AHCFREE_PLUGIN_MAIN_FILE) ?>" /></a></h1><br />
|
8 |
<div class="panel">
|
9 |
<h2 style="height:35px !important; font-size:13px !important">Settings</h2>
|
10 |
<option value="<?php echo $value; ?>" <?php echo ( $value == $custom_timezone_offset ) ? 'selected' : ''; ?>><?php echo $value; ?></option>
|
11 |
global $wp_roles;
|
12 |
if ( !isset( $wp_roles ) ) $wp_roles = new WP_Roles();
|
13 |
$available_roles_names = $wp_roles->get_names();//we get all roles names
|
14 |
$available_roles_capable = array();
|
15 |
foreach ($available_roles_names as $role_key => $role_name) { //we iterate all the names
|
16 |
$role_object = get_role( $role_key );//we get the Role Object
|
17 |
$array_of_capabilities = $role_object->capabilities;//we get the array of capabilities for this role
|
18 |
if($array_of_capabilities['update_plugins'] == 1 || $array_of_capabilities['manage_links'] == 1 || $array_of_capabilities['manage_sites'] == 1 ){ //we check if the upload_files capability is present, and if its present check if its 0 (FALSE in Php)
|
19 |
$available_roles_capable[$role_key] = $role_name; //we populate the array of capable roles
|
20 |
}
|
21 |
}
|
22 |
|
23 |
select: \'#ahcUserRoles\'
|
24 |
+
</div>
|
25 |
+
</form>
|
css/ar_css.css
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
html {height: 100%}
|
3 |
body {height: 100%; margin:0; padding:0; overflow-x:hidden; font: 10px verdana;}
|
4 |
|
5 |
-
.
|
6 |
direction: rtl; /* ## */
|
7 |
padding: 60px 20px;
|
8 |
}
|
2 |
html {height: 100%}
|
3 |
body {height: 100%; margin:0; padding:0; overflow-x:hidden; font: 10px verdana;}
|
4 |
|
5 |
+
.ahcfree_main_container{
|
6 |
direction: rtl; /* ## */
|
7 |
padding: 60px 20px;
|
8 |
}
|
css/en_newcss.css
DELETED
@@ -1,115 +0,0 @@
|
|
1 |
-
body {font: 10px verdana; background:#F1F1F1 !important}
|
2 |
-
|
3 |
-
.legendsContainer{min-height: 410px; border: solid 1px #CCCCCC; border-radius: 5px; width:200px !important; padding: 10px; background-color: #F1F1F1;}
|
4 |
-
.legendsContainer div.legend{float: left;display:inline; height:auto; width:180px !important; margin: 0 10px 10px 0;}
|
5 |
-
div.legend span{font-size: 12px; line-height: 0.9;}
|
6 |
-
div.legend span.color{display: block; float: left; width: 15px; height: 95%; margin-right: 8px;}
|
7 |
-
div.legend span.name{margin-right: 5px;}
|
8 |
-
div.legend span.value{color: #D34E4E;}
|
9 |
-
.panel{
|
10 |
-
margin-left:20px
|
11 |
-
}
|
12 |
-
|
13 |
-
.disabled_panel{
|
14 |
-
background:#666;
|
15 |
-
position:absolute
|
16 |
-
|
17 |
-
}
|
18 |
-
|
19 |
-
.ahc_main_container{
|
20 |
-
direction: ltr; /* ## */
|
21 |
-
font-family:Verdana, Geneva, sans-serif; font-size:8px !important;
|
22 |
-
width:98%;
|
23 |
-
}
|
24 |
-
.ahc_main_container h1{
|
25 |
-
font-size:20px;
|
26 |
-
font-weight:normal;
|
27 |
-
color:#657f97;
|
28 |
-
|
29 |
-
}
|
30 |
-
.hitsLogo{
|
31 |
-
background:url(../images/hitslogo.png) left no-repeat;
|
32 |
-
height:55px;
|
33 |
-
width:55px;
|
34 |
-
display:inline;
|
35 |
-
float:left;
|
36 |
-
}
|
37 |
-
.rightPanelsContainer{float: left; /* ## */ margin: 0; padding: 0;}
|
38 |
-
.leftPanelsContainer{float: right; /* ## */ margin: 0; padding: 0;}
|
39 |
-
.cleaner{clear: both;}
|
40 |
-
.panel, .panelcollapsed{
|
41 |
-
background: #23282D;
|
42 |
-
border:#23282D solid 1px;
|
43 |
-
margin: 10px 0px;
|
44 |
-
-moz-border-radius: 4px;
|
45 |
-
-webkit-border-radius: 4px;
|
46 |
-
|
47 |
-
}
|
48 |
-
.panel h2, .panelcollapsed h2{
|
49 |
-
font-size: 12px !important;
|
50 |
-
font-weight: normal !important;
|
51 |
-
margin: 0px !important;
|
52 |
-
|
53 |
-
background-color:#666 !important;
|
54 |
-
padding:5px !important;
|
55 |
-
|
56 |
-
color: white !important;
|
57 |
-
font-weight:bold !important;
|
58 |
-
background-color:#23282D;
|
59 |
-
|
60 |
-
-moz-border-radius: 3px !important;
|
61 |
-
-webkit-border-radius: 3px !important;
|
62 |
-
height:20px !important;
|
63 |
-
}
|
64 |
-
.panelcollapsed h2{
|
65 |
-
background: #FFF url(../images/arrow_down.png) no-repeat 99% 50% !important;; /* ## */
|
66 |
-
border-color: #CCC !important;;
|
67 |
-
}
|
68 |
-
.panelcontent{
|
69 |
-
padding: 10px;
|
70 |
-
background: #FFF;
|
71 |
-
min-height:400px;
|
72 |
-
}
|
73 |
-
.panelcollapsed .panelcontent {display: none;}
|
74 |
-
.panelcontent th{font-size: 12px; color: #657f97; font-weight: 0; padding: 5px; text-align: left; border-bottom:#CCC solid 1px; }
|
75 |
-
.panelcontent td, .panelcontent td.values{text-align: left; color:#000; font-size: 12px; font-weight: 0; padding: 5px; text-align: left; border-bottom:#EFEFEF solid 1px}
|
76 |
-
.panelcontent tr:hover{
|
77 |
-
background:#F5F5F5
|
78 |
-
}
|
79 |
-
|
80 |
-
.fineFont{font-size: 10px !important}
|
81 |
-
|
82 |
-
.lastVisitorsDetails{border-bottom: solid 1px #dad6ca; direction: ltr; padding: 5px;}
|
83 |
-
.lastVisitorsDetails span{margin-right: 3px;}
|
84 |
-
.lastVisitorsDetails img{vertical-align: middle;}
|
85 |
-
.ipAddress{float: left; font-size: 14px; color: #3B9EF9; margin-bottom: 10px; margin-bottom: 10px;}
|
86 |
-
.referingSite{color: #3B9EF9; margin-left: 5px; font-size: 12px;}
|
87 |
-
.visitDateTime{float: right; color: #3B9EF9; font-size: 12px;}
|
88 |
-
|
89 |
-
.lastSearchKeyWords, .visitorMarker{border-bottom: solid 1px #dad6ca; direction: ltr; padding: 5px;}
|
90 |
-
.lastSearchKeyWords span, .countryMarker span{margin-right: 3px;}
|
91 |
-
.lastSearchKeyWords img{vertical-align: middle;}
|
92 |
-
.countryMarker{direction: ltr; padding: 5px;}
|
93 |
-
.searchKeyWords{font-size: 14px;}
|
94 |
-
|
95 |
-
.languageChanger{direction: rtl; /* ## */ font-size: 18px;}
|
96 |
-
|
97 |
-
.countryMarker span.countryName, .visitorMarker span.ipAddress{margin-left: 5px;}
|
98 |
-
|
99 |
-
.visitorMarker{border-bottom: dashed 1px #dad6ca;}
|
100 |
-
.countryMarker span.countryName{font-size: 12px;}
|
101 |
-
.countryMarker img{vertical-align: middle;}
|
102 |
-
.visitorMarker span.ipAddress{font-size: 12px;}
|
103 |
-
.visitorMarker span{float: left;}
|
104 |
-
|
105 |
-
/* visitors graph begin */
|
106 |
-
div.visitorsGraphContainer{float: left; width: 70%} /* ### */
|
107 |
-
div.visitorsGraphContainer div.visitorsGraph{float: left; background-color: #82CE69; border-radius: 2px;}
|
108 |
-
div.visitorsPercent{float: left; width: 25%; margin-left: 5px;} /* ### */
|
109 |
-
/* visitors graph end */
|
110 |
-
|
111 |
-
h2{
|
112 |
-
text-align:left !important;
|
113 |
-
font-size:14px !important;
|
114 |
-
height:30px !important;
|
115 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
css/eng_css.css
ADDED
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
body {background:#F1F1F1 !important}
|
2 |
+
|
3 |
+
|
4 |
+
.show-swal2{
|
5 |
+
width:700px !important;
|
6 |
+
height:500px !important;
|
7 |
+
}
|
8 |
+
|
9 |
+
.box_widget{
|
10 |
+
height:130px;
|
11 |
+
font-family:'Open Sans', sans-serif;
|
12 |
+
color:#FFF;
|
13 |
+
font-size:40px;
|
14 |
+
text-align:right;
|
15 |
+
padding-right:10px;
|
16 |
+
padding-top:10px;
|
17 |
+
|
18 |
+
}
|
19 |
+
.smallinputs{
|
20 |
+
width:40px !important;
|
21 |
+
background:#333
|
22 |
+
}
|
23 |
+
.txt
|
24 |
+
{
|
25 |
+
font-size:20px;
|
26 |
+
}
|
27 |
+
|
28 |
+
|
29 |
+
#ahcfree_currenttime{
|
30 |
+
color:gray;
|
31 |
+
font-size:20px !important;
|
32 |
+
float:right !important;
|
33 |
+
vertical-align:middle
|
34 |
+
}
|
35 |
+
|
36 |
+
.blueBox{
|
37 |
+
background:url("../images/visits.png") no-repeat;
|
38 |
+
background-position:bottom left;
|
39 |
+
background-color:#578ebe;
|
40 |
+
}
|
41 |
+
|
42 |
+
.redBox{
|
43 |
+
background:url("../images/visitors.png") no-repeat;
|
44 |
+
background-position:bottom left;
|
45 |
+
background-color:#e35b5a;
|
46 |
+
|
47 |
+
}
|
48 |
+
|
49 |
+
.greenBox{
|
50 |
+
background:url("../images/online.png") no-repeat;
|
51 |
+
background-position:bottom left;
|
52 |
+
background-color:#44b6ae;
|
53 |
+
}
|
54 |
+
|
55 |
+
.movBox{
|
56 |
+
background:url("../images/searchengin.png") no-repeat;
|
57 |
+
background-position:bottom left;
|
58 |
+
background-color:#8775a7;
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
.legendsContainer{ border: solid 1px #CCCCCC; border-radius: 5px; width:auto !important; height:auto; padding: 10px; background-color: #F1F1F1;}
|
63 |
+
.legendsContainer div.legend{float: left;display:inline; height: 15px; width:180px !important; margin: 0 10px 10px 0;}
|
64 |
+
div.legend span{font-size: 12px; line-height: 0.9;}
|
65 |
+
div.legend span.color{display: block; float: left; width: 15px; height: 95%; margin-right: 8px;}
|
66 |
+
div.legend span.name{margin-right: 5px;}
|
67 |
+
div.legend span.value{color: #D34E4E;}
|
68 |
+
|
69 |
+
.panel{
|
70 |
+
margin-left:20px;
|
71 |
+
font-size:15px;
|
72 |
+
}
|
73 |
+
|
74 |
+
.disabled_panel{
|
75 |
+
background:#666;
|
76 |
+
position:absolute
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
.ahcfree_main_container{
|
81 |
+
direction: ltr; /* ## */
|
82 |
+
font-family:Verdana, Geneva, sans-serif; font-size:8px !important;
|
83 |
+
width:98%;
|
84 |
+
}
|
85 |
+
.ahcfree_main_container h1{
|
86 |
+
font-size:20px;
|
87 |
+
font-weight:normal;
|
88 |
+
color:#657f97;
|
89 |
+
|
90 |
+
}
|
91 |
+
.hitsLogo{
|
92 |
+
background:url(../images/hitslogo.png) left no-repeat;
|
93 |
+
height:55px;
|
94 |
+
width:55px;
|
95 |
+
display:inline;
|
96 |
+
float:left;
|
97 |
+
}
|
98 |
+
.rightPanelsContainer{float: left; /* ## */ margin: 0; padding: 0;}
|
99 |
+
.leftPanelsContainer{float: right; /* ## */ margin: 0; padding: 0;}
|
100 |
+
.cleaner{clear: both;}
|
101 |
+
.panel, .panelcollapsed{
|
102 |
+
background: #eee;
|
103 |
+
border:#dfdfdf solid 1px;
|
104 |
+
margin: 10px 0px;
|
105 |
+
padding: 0px 0px 5px;
|
106 |
+
-moz-border-radius: 4px;
|
107 |
+
-webkit-border-radius: 4px;
|
108 |
+
|
109 |
+
}
|
110 |
+
.panel h2, .panelcollapsed h2{
|
111 |
+
font-size: 12px !important;
|
112 |
+
font-weight: normal !important;
|
113 |
+
margin: 0px !important;
|
114 |
+
padding: 4px !important;
|
115 |
+
background: url(../images/headerbg.png) repeat-x !important; /* ## */
|
116 |
+
border-bottom:#dfdfdf solid 1px !important;;
|
117 |
+
-moz-border-radius: 3px !important;
|
118 |
+
-webkit-border-radius: 3px !important;
|
119 |
+
height:23px !important;
|
120 |
+
background-color:#FFF !important;
|
121 |
+
padding-top:10px !important;
|
122 |
+
padding-left:7px !important;
|
123 |
+
color: #657f97 !important;
|
124 |
+
font-weight:bold !important;
|
125 |
+
}
|
126 |
+
.panelcollapsed h2{
|
127 |
+
background: #FFF url(../images/arrow_down.png) no-repeat 99% 50% !important;; /* ## */
|
128 |
+
border-color: #CCC !important;;
|
129 |
+
}
|
130 |
+
.panelcontent{
|
131 |
+
padding: 10px;
|
132 |
+
background: #FFF;
|
133 |
+
|
134 |
+
}
|
135 |
+
.panelcollapsed .panelcontent {display: none;}
|
136 |
+
.panelcontent th{font-size: 12px; color: #657f97; font-weight: 0; padding: 5px; text-align: left; border-bottom:#CCC solid 1px; }
|
137 |
+
.panelcontent td, .panelcontent td.values{text-align: left; font-size:14px; font-weight: 0; padding: 5px; text-align: left; border-bottom:#EFEFEF solid 1px}
|
138 |
+
.panelcontent tr:hover{
|
139 |
+
background:#F5F5F5
|
140 |
+
}
|
141 |
+
|
142 |
+
.fineFont{font-size: 10px !important}
|
143 |
+
|
144 |
+
.lastVisitorsDetails{border-bottom: solid 1px #dad6ca; direction: ltr; padding: 5px;}
|
145 |
+
.lastVisitorsDetails span{margin-right: 3px;}
|
146 |
+
.lastVisitorsDetails img{vertical-align: middle;}
|
147 |
+
.ipAddress{float: left; font-size: 14px; color: #3B9EF9; margin-bottom: 10px; margin-bottom: 10px; width:150px;}
|
148 |
+
.referingSite{color: #3B9EF9; margin-left: 5px; font-size: 12px;}
|
149 |
+
.visitDateTime{float: right; color: #3B9EF9; font-size: 12px;}
|
150 |
+
|
151 |
+
.lastSearchKeyWords, .visitorMarker{border-bottom: solid 1px #dad6ca; direction: ltr; padding: 5px;}
|
152 |
+
.lastSearchKeyWords span, .countryMarker span{margin-right: 3px;}
|
153 |
+
.lastSearchKeyWords img{vertical-align: middle;}
|
154 |
+
.countryMarker{direction: ltr; padding: 5px;}
|
155 |
+
.searchKeyWords{font-size: 14px;}
|
156 |
+
|
157 |
+
.languageChanger{direction: rtl; /* ## */ font-size: 18px;}
|
158 |
+
|
159 |
+
.countryMarker span.countryName, .visitorMarker span.ipAddress{margin-left: 5px;}
|
160 |
+
|
161 |
+
.visitorMarker{border-bottom: dashed 1px #dad6ca;}
|
162 |
+
.countryMarker span.countryName{font-size: 12px;}
|
163 |
+
.countryMarker img{vertical-align: middle;}
|
164 |
+
.visitorMarker span.ipAddress{font-size: 12px;}
|
165 |
+
.visitorMarker span{float: left;}
|
166 |
+
|
167 |
+
/* visitors graph begin */
|
168 |
+
div.visitorsGraphContainer{float: left; width: 70%} /* ### */
|
169 |
+
div.visitorsGraphContainer div.visitorsGraph{float: left; background-color:#9F6; border-radius: 2px;}
|
170 |
+
div.visitorsGraphContainer div.visitorsGraph2{float: left; background-color:#393; border-radius: 2px;}
|
171 |
+
div.visitorsGraphContainer div.visitorsGraph3{float: left; background-color:#060; border-radius: 2px;}
|
172 |
+
div.visitorsPercent{float: left; width: 25%; margin-left: 5px;} /* ### */
|
173 |
+
/* visitors graph end */
|
174 |
+
|
175 |
+
h2{
|
176 |
+
text-align:left !important;
|
177 |
+
font-size:14px !important;
|
178 |
+
height:30px !important;
|
179 |
+
}
|
180 |
+
|
181 |
+
|
182 |
+
.recentv tr td{
|
183 |
+
font-size:12px !important;
|
184 |
+
}
|
185 |
+
|
186 |
+
/*************************************/
|
187 |
+
|
188 |
+
.increase_counter{
|
189 |
+
background-image:url('../images/increase.png');
|
190 |
+
}
|
191 |
+
|
192 |
+
.decrease_counter{
|
193 |
+
background-image:url('../images/decrease.png');
|
194 |
+
}
|
195 |
+
span#up-down {
|
196 |
+
display: inline-block;
|
197 |
+
width: 50px;
|
198 |
+
height: 30px;
|
199 |
+
background-repeat: no-repeat;
|
200 |
+
background-position: center center;
|
201 |
+
}
|
202 |
+
|
203 |
+
.hits_duration_select{
|
204 |
+
padding-top: 10px;
|
205 |
+
padding-left: 10px;
|
206 |
+
}
|
207 |
+
#visitors_graph_stats{
|
208 |
+
position:relative;
|
209 |
+
}
|
210 |
+
.panelcontent.loader:after {
|
211 |
+
content: "";
|
212 |
+
background-image: url(../images/Spinner-1s-200px.svg);
|
213 |
+
background-repeat: no-repeat;
|
214 |
+
width: 100%;
|
215 |
+
height: 100%;
|
216 |
+
position: absolute;
|
217 |
+
left: 0;
|
218 |
+
top: 0;
|
219 |
+
background-position: center;
|
220 |
+
z-index: 9999;
|
221 |
+
background-color: rgba(255,255,255,0.6);
|
222 |
+
}
|
css/{en_css.css → engl_css.css}
RENAMED
@@ -1,13 +1,71 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
|
4 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
div.legend span{font-size: 12px; line-height: 0.9;}
|
6 |
div.legend span.color{display: block; float: left; width: 15px; height: 95%; margin-right: 8px;}
|
7 |
div.legend span.name{margin-right: 5px;}
|
8 |
div.legend span.value{color: #D34E4E;}
|
|
|
9 |
.panel{
|
10 |
-
margin-left:20px
|
|
|
11 |
}
|
12 |
|
13 |
.disabled_panel{
|
@@ -16,12 +74,12 @@ position:absolute
|
|
16 |
|
17 |
}
|
18 |
|
19 |
-
.
|
20 |
direction: ltr; /* ## */
|
21 |
font-family:Verdana, Geneva, sans-serif; font-size:8px !important;
|
22 |
width:98%;
|
23 |
}
|
24 |
-
.
|
25 |
font-size:20px;
|
26 |
font-weight:normal;
|
27 |
color:#657f97;
|
@@ -50,18 +108,17 @@ float:left;
|
|
50 |
font-size: 12px !important;
|
51 |
font-weight: normal !important;
|
52 |
margin: 0px !important;
|
53 |
-
|
54 |
-
background-
|
|
|
|
|
|
|
|
|
|
|
55 |
padding-top:10px !important;
|
56 |
padding-left:7px !important;
|
57 |
color: #657f97 !important;
|
58 |
font-weight:bold !important;
|
59 |
-
padding: 4px !important;
|
60 |
-
background: url(../images/myheaderbg.png) repeat-x !important; /* ## */
|
61 |
-
|
62 |
-
-moz-border-radius: 3px !important;
|
63 |
-
-webkit-border-radius: 3px !important;
|
64 |
-
height:20px !important;
|
65 |
}
|
66 |
.panelcollapsed h2{
|
67 |
background: #FFF url(../images/arrow_down.png) no-repeat 99% 50% !important;; /* ## */
|
@@ -70,11 +127,11 @@ float:left;
|
|
70 |
.panelcontent{
|
71 |
padding: 10px;
|
72 |
background: #FFF;
|
73 |
-
|
74 |
}
|
75 |
.panelcollapsed .panelcontent {display: none;}
|
76 |
.panelcontent th{font-size: 12px; color: #657f97; font-weight: 0; padding: 5px; text-align: left; border-bottom:#CCC solid 1px; }
|
77 |
-
.panelcontent td, .panelcontent td.values{text-align: left;
|
78 |
.panelcontent tr:hover{
|
79 |
background:#F5F5F5
|
80 |
}
|
@@ -84,7 +141,7 @@ background:#F5F5F5
|
|
84 |
.lastVisitorsDetails{border-bottom: solid 1px #dad6ca; direction: ltr; padding: 5px;}
|
85 |
.lastVisitorsDetails span{margin-right: 3px;}
|
86 |
.lastVisitorsDetails img{vertical-align: middle;}
|
87 |
-
.ipAddress{float: left; font-size: 14px; color: #3B9EF9; margin-bottom: 10px; margin-bottom: 10px;}
|
88 |
.referingSite{color: #3B9EF9; margin-left: 5px; font-size: 12px;}
|
89 |
.visitDateTime{float: right; color: #3B9EF9; font-size: 12px;}
|
90 |
|
@@ -106,7 +163,9 @@ background:#F5F5F5
|
|
106 |
|
107 |
/* visitors graph begin */
|
108 |
div.visitorsGraphContainer{float: left; width: 70%} /* ### */
|
109 |
-
div.visitorsGraphContainer div.visitorsGraph{float: left; background-color
|
|
|
|
|
110 |
div.visitorsPercent{float: left; width: 25%; margin-left: 5px;} /* ### */
|
111 |
/* visitors graph end */
|
112 |
|
@@ -115,3 +174,46 @@ h2{
|
|
115 |
font-size:14px !important;
|
116 |
height:30px !important;
|
117 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.show-swal2{
|
2 |
+
width:700px !important;
|
3 |
+
height:500px !important;
|
4 |
+
}
|
5 |
+
|
6 |
+
.box_widget{
|
7 |
+
height:130px;
|
8 |
+
font-family:'Open Sans', sans-serif;
|
9 |
+
color:#FFF;
|
10 |
+
font-size:40px;
|
11 |
+
text-align:right;
|
12 |
+
padding-right:10px;
|
13 |
+
padding-top:10px;
|
14 |
|
15 |
+
}
|
16 |
+
.smallinputs{
|
17 |
+
width:40px !important;
|
18 |
+
background:#333
|
19 |
+
}
|
20 |
+
.txt
|
21 |
+
{
|
22 |
+
font-size:20px;
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
#ahcfree_currenttime{
|
27 |
+
color:gray;
|
28 |
+
font-size:15px !important;
|
29 |
+
float:right !important;
|
30 |
+
vertical-align:middle
|
31 |
+
}
|
32 |
+
|
33 |
+
.blueBox{
|
34 |
+
background:url("../images/visits.png") no-repeat;
|
35 |
+
background-position:bottom left;
|
36 |
+
background-color:#578ebe;
|
37 |
+
}
|
38 |
+
|
39 |
+
.redBox{
|
40 |
+
background:url("../images/visitors.png") no-repeat;
|
41 |
+
background-position:bottom left;
|
42 |
+
background-color:#e35b5a;
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
.greenBox{
|
47 |
+
background:url("../images/online.png") no-repeat;
|
48 |
+
background-position:bottom left;
|
49 |
+
background-color:#44b6ae;
|
50 |
+
}
|
51 |
+
|
52 |
+
.movBox{
|
53 |
+
background:url("../images/searchengin.png") no-repeat;
|
54 |
+
background-position:bottom left;
|
55 |
+
background-color:#8775a7;
|
56 |
+
}
|
57 |
+
|
58 |
+
|
59 |
+
.legendsContainer{ border: solid 1px #CCCCCC; border-radius: 5px; width:auto !important; height:auto; padding: 10px; background-color: #F1F1F1;}
|
60 |
+
.legendsContainer div.legend{float: left;display:inline; height: 15px; width:180px !important; margin: 0 10px 10px 0;}
|
61 |
div.legend span{font-size: 12px; line-height: 0.9;}
|
62 |
div.legend span.color{display: block; float: left; width: 15px; height: 95%; margin-right: 8px;}
|
63 |
div.legend span.name{margin-right: 5px;}
|
64 |
div.legend span.value{color: #D34E4E;}
|
65 |
+
|
66 |
.panel{
|
67 |
+
margin-left:20px;
|
68 |
+
font-size:15px;
|
69 |
}
|
70 |
|
71 |
.disabled_panel{
|
74 |
|
75 |
}
|
76 |
|
77 |
+
.ahcfree_main_container{
|
78 |
direction: ltr; /* ## */
|
79 |
font-family:Verdana, Geneva, sans-serif; font-size:8px !important;
|
80 |
width:98%;
|
81 |
}
|
82 |
+
.ahcfree_main_container h1{
|
83 |
font-size:20px;
|
84 |
font-weight:normal;
|
85 |
color:#657f97;
|
108 |
font-size: 12px !important;
|
109 |
font-weight: normal !important;
|
110 |
margin: 0px !important;
|
111 |
+
padding: 4px !important;
|
112 |
+
background: url(../images/headerbg.png) repeat-x !important; /* ## */
|
113 |
+
border-bottom:#dfdfdf solid 1px !important;;
|
114 |
+
-moz-border-radius: 3px !important;
|
115 |
+
-webkit-border-radius: 3px !important;
|
116 |
+
height:23px !important;
|
117 |
+
background-color:#FFF !important;
|
118 |
padding-top:10px !important;
|
119 |
padding-left:7px !important;
|
120 |
color: #657f97 !important;
|
121 |
font-weight:bold !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
}
|
123 |
.panelcollapsed h2{
|
124 |
background: #FFF url(../images/arrow_down.png) no-repeat 99% 50% !important;; /* ## */
|
127 |
.panelcontent{
|
128 |
padding: 10px;
|
129 |
background: #FFF;
|
130 |
+
|
131 |
}
|
132 |
.panelcollapsed .panelcontent {display: none;}
|
133 |
.panelcontent th{font-size: 12px; color: #657f97; font-weight: 0; padding: 5px; text-align: left; border-bottom:#CCC solid 1px; }
|
134 |
+
.panelcontent td, .panelcontent td.values{text-align: left; font-size:14px; font-weight: 0; padding: 5px; text-align: left; border-bottom:#EFEFEF solid 1px}
|
135 |
.panelcontent tr:hover{
|
136 |
background:#F5F5F5
|
137 |
}
|
141 |
.lastVisitorsDetails{border-bottom: solid 1px #dad6ca; direction: ltr; padding: 5px;}
|
142 |
.lastVisitorsDetails span{margin-right: 3px;}
|
143 |
.lastVisitorsDetails img{vertical-align: middle;}
|
144 |
+
.ipAddress{float: left; font-size: 14px; color: #3B9EF9; margin-bottom: 10px; margin-bottom: 10px; width:150px;}
|
145 |
.referingSite{color: #3B9EF9; margin-left: 5px; font-size: 12px;}
|
146 |
.visitDateTime{float: right; color: #3B9EF9; font-size: 12px;}
|
147 |
|
163 |
|
164 |
/* visitors graph begin */
|
165 |
div.visitorsGraphContainer{float: left; width: 70%} /* ### */
|
166 |
+
div.visitorsGraphContainer div.visitorsGraph{float: left; background-color:#9F6; border-radius: 2px;}
|
167 |
+
div.visitorsGraphContainer div.visitorsGraph2{float: left; background-color:#393; border-radius: 2px;}
|
168 |
+
div.visitorsGraphContainer div.visitorsGraph3{float: left; background-color:#060; border-radius: 2px;}
|
169 |
div.visitorsPercent{float: left; width: 25%; margin-left: 5px;} /* ### */
|
170 |
/* visitors graph end */
|
171 |
|
174 |
font-size:14px !important;
|
175 |
height:30px !important;
|
176 |
}
|
177 |
+
|
178 |
+
|
179 |
+
.recentv tr td{
|
180 |
+
font-size:12px !important;
|
181 |
+
}
|
182 |
+
|
183 |
+
/*************************************/
|
184 |
+
|
185 |
+
.increase_counter{
|
186 |
+
background-image:url('../images/increase.png');
|
187 |
+
}
|
188 |
+
|
189 |
+
.decrease_counter{
|
190 |
+
background-image:url('../images/decrease.png');
|
191 |
+
}
|
192 |
+
span#up-down {
|
193 |
+
display: inline-block;
|
194 |
+
width: 50px;
|
195 |
+
height: 30px;
|
196 |
+
background-repeat: no-repeat;
|
197 |
+
background-position: center center;
|
198 |
+
}
|
199 |
+
|
200 |
+
.hits_duration_select{
|
201 |
+
padding-top: 10px;
|
202 |
+
padding-left: 10px;
|
203 |
+
}
|
204 |
+
#visitors_graph_stats{
|
205 |
+
position:relative;
|
206 |
+
}
|
207 |
+
.panelcontent.loader:after {
|
208 |
+
content: "";
|
209 |
+
background-image: url(../images/Spinner-1s-200px.svg);
|
210 |
+
background-repeat: no-repeat;
|
211 |
+
width: 100%;
|
212 |
+
height: 100%;
|
213 |
+
position: absolute;
|
214 |
+
left: 0;
|
215 |
+
top: 0;
|
216 |
+
background-position: center;
|
217 |
+
z-index: 9999;
|
218 |
+
background-color: rgba(255,255,255,0.6);
|
219 |
+
}
|
css/jquery.jqplot.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em}.jqplot-axis{font-size:.75em}.jqplot-xaxis{margin-top:10px}.jqplot-x2axis{margin-bottom:10px}.jqplot-yaxis{margin-right:10px}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis,.jqplot-yMidAxis{margin-left:10px;margin-right:10px}.jqplot-axis-tick,.jqplot-xaxis-tick,.jqplot-yaxis-tick,.jqplot-x2axis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick,.jqplot-yMidAxis-tick{position:absolute;white-space:pre}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom}.jqplot-yaxis-tick{right:0;top:15px;text-align:right}.jqplot-yaxis-tick.jqplot-breakTick{right:-20px;margin-right:0;padding:1px 5px 1px 5px;z-index:2;font-size:1.5em}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left}.jqplot-yMidAxis-tick{text-align:center;white-space:nowrap}.jqplot-xaxis-label{margin-top:10px;font-size:11pt;position:absolute}.jqplot-x2axis-label{margin-bottom:10px;font-size:11pt;position:absolute}.jqplot-yaxis-label{margin-right:10px;font-size:11pt;position:absolute}.jqplot-yMidAxis-label{font-size:11pt;position:absolute}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;margin-left:10px;position:absolute}.jqplot-meterGauge-tick{font-size:.75em;color:#999}.jqplot-meterGauge-label{font-size:1em;color:#999}table.jqplot-table-legend{margin-top:12px;margin-bottom:12px;margin-left:12px;margin-right:12px}table.jqplot-table-legend,table.jqplot-cursor-legend{background-color:rgba(255,255,255,0.6);border:1px solid #ccc;position:absolute;font-size:.75em}td.jqplot-table-legend{vertical-align:middle}td.jqplot-seriesToggle:hover,td.jqplot-seriesToggle:active{cursor:pointer}.jqplot-table-legend .jqplot-series-hidden{text-decoration:line-through}div.jqplot-table-legend-swatch-outline{border:1px solid #ccc;padding:1px}div.jqplot-table-legend-swatch{width:0;height:0;border-top-width:5px;border-bottom-width:5px;border-left-width:6px;border-right-width:6px;border-top-style:solid;border-bottom-style:solid;border-left-style:solid;border-right-style:solid}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em}.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px}.jqplot-highlighter-tooltip,.jqplot-canvasOverlay-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px}.jqplot-point-label{font-size:.75em;z-index:2}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em}.jqplot-error{text-align:center}.jqplot-error-message{position:relative;top:46%;display:inline-block}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%)}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,0.7)}div.jqplot-noData-container{text-align:center;background-color:rgba(96%,96%,96%,0.3)}
|
css/sweetalerts.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.swal-noscroll{height:auto !important}.swal2-modal,.swal2-overlay{position:fixed;display:none}.swal2-overlay{background-color:rgba(0,0,0,.4);left:0;right:0;top:0;bottom:0;z-index:1000}.swal2-modal{background-color:#fff;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;border-radius:5px;box-sizing:border-box;text-align:center;left:50%;top:50%;margin-top:-200px;max-height:90%;overflow-x:hidden;overflow-y:auto;z-index:2000}.swal2-modal:focus{outline:0}.swal2-modal.loading{overflow-y:hidden}.swal2-modal h2{color:#575757;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:0;padding:0;line-height:60px;display:block}.swal2-modal .swal2-spacer{height:10px;color:transparent;border:0}.swal2-modal button.styled{color:#fff;border:0;box-shadow:none;font-size:17px;font-weight:500;border-radius:3px;padding:10px 32px;margin:0 5px;cursor:pointer}.swal2-content,.swal2-icon{padding:0;position:relative}.swal2-modal button.styled:not(.loading)[disabled]{opacity:.4;cursor:no-drop}.swal2-modal button.styled.loading{box-sizing:border-box;border:4px solid transparent;width:40px;height:40px;padding:0;margin:-2px 30px;vertical-align:top;background-color:transparent!important;color:transparent;cursor:default;border-radius:100%;-webkit-animation:rotate-loading 1.5s linear 0s infinite normal;animation:rotate-loading 1.5s linear 0s infinite normal}.swal2-modal button:not(.styled).loading:after{display:inline-block;content:"";margin-left:5px;vertical-align:-1px;height:6px;width:6px;border:3px solid #999;border-right-color:transparent;border-radius:50%;-webkit-animation:rotate-loading 1.5s linear 0s infinite normal;animation:rotate-loading 1.5s linear 0s infinite normal}.swal2-checkbox input,.swal2-checkbox span,.swal2-radio input,.swal2-radio span{vertical-align:middle}.swal2-modal .swal2-image{margin:20px auto;max-width:100%}.swal2-modal .swal2-close{font-size:36px;line-height:36px;font-family:serif;position:absolute;top:5px;right:13px;cursor:pointer;color:#cfcfcf;-webkit-transition:all .1s ease;transition:all .1s ease}.swal2-modal .swal2-close:hover{color:#d55}.swal2-modal>.swal2-checkbox,.swal2-modal>.swal2-input,.swal2-modal>.swal2-radio,.swal2-modal>.swal2-select,.swal2-modal>.swal2-textarea{display:none}.swal2-content{font-size:18px;text-align:center;font-weight:300;float:none;margin:0;line-height:normal;color:#555}.swal2-icon.swal2-info,.swal2-icon.swal2-question,.swal2-icon.swal2-warning{font-size:60px;line-height:80px;text-align:center}.swal2-icon{width:80px;height:80px;border:4px solid grey;border-radius:50%;margin:20px auto 30px;box-sizing:content-box;cursor:default;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-icon.swal2-error{border-color:#f27474}.swal2-icon.swal2-error .x-mark{position:relative;display:block}.swal2-icon.swal2-error .line{position:absolute;height:5px;width:47px;background-color:#f27474;display:block;top:37px;border-radius:2px}.swal2-icon.swal2-error .line.left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.swal2-icon.swal2-error .line.right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.swal2-icon.swal2-warning{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;color:#f8bb86;border-color:#f8bb86}.swal2-icon.swal2-info{font-family:"Open Sans",sans-serif;color:#3fc3ee;border-color:#3fc3ee}.swal2-icon.swal2-question{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;color:#c9dae1;border-color:#c9dae1}.swal2-icon.swal2-success{border-color:#a5dc86}.swal2-icon.swal2-success::after,.swal2-icon.swal2-success::before{content:'';position:absolute;width:60px;height:120px;background:#fff}.swal2-icon.swal2-success::before{border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.swal2-icon.swal2-success::after{border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.swal2-icon.swal2-success .placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.swal2-icon.swal2-success .fix{width:7px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-icon.swal2-success .line{height:5px;background-color:#a5dc86;display:block;border-radius:2px;position:absolute;z-index:2}.swal2-icon.swal2-success .line.tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-success .line.long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-checkbox,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea{margin:20px auto}.swal2-input:not([type=file]),.swal2-textarea{width:100%;box-sizing:border-box;border-radius:3px;border:1px solid #d7d7d7;font-size:18px;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);-webkit-transition:all .3s;transition:all .3s}.swal2-input:not([type=file]).error,.swal2-textarea.error{border-color:#f06e57!important}.swal2-input:not([type=file]):focus,.swal2-textarea:focus{outline:0;box-shadow:0 0 3px #c4e6f5;border:1px solid #b4dbed}.swal2-input:not([type=file]):focus::-moz-placeholder,.swal2-textarea:focus::-moz-placeholder{-webkit-transition:opacity .3s 30ms ease;transition:opacity .3s 30ms ease;opacity:.8}.swal2-input:not([type=file]):focus:-ms-input-placeholder,.swal2-textarea:focus:-ms-input-placeholder{-webkit-transition:opacity .3s 30ms ease;transition:opacity .3s 30ms ease;opacity:.8}.swal2-input:not([type=file]):focus::-webkit-input-placeholder,.swal2-textarea:focus::-webkit-input-placeholder{-webkit-transition:opacity .3s 30ms ease;transition:opacity .3s 30ms ease;opacity:.8}.swal2-input:not([type=file])::-moz-placeholder,.swal2-textarea::-moz-placeholder{color:#bdbdbd}.swal2-input:not([type=file]):-ms-input-placeholder,.swal2-textarea:-ms-input-placeholder{color:#bdbdbd}.swal2-input:not([type=file])::-webkit-input-placeholder,.swal2-textarea::-webkit-input-placeholder{color:#bdbdbd}.swal2-input:not([type=file]){height:43px;padding:0 12px}.swal2-input[type=file]{font-size:20px}.swal2-textarea{height:108px;padding:12px}.swal2-select{color:#555;font-size:inherit;padding:5px 10px;min-width:40%;max-width:100%}.swal2-radio{border:0}.swal2-radio label:not(:first-child){margin-left:20px}.swal2-radio input{margin:0 3px 0 0}.swal2-checkbox{color:#555}.swal2-validationerror{background-color:#f1f1f1;margin:0 -20px;overflow:hidden;padding:10px;color:#797979;font-size:16px;font-weight:300;display:none}.swal2-validationerror::before{content:"!";display:inline-block;width:24px;height:24px;border-radius:50%;background-color:#ea7d7d;color:#fff;line-height:24px;text-align:center;margin-right:10px}@-webkit-keyframes showSweetAlert{0%{-webkit-transform:scale(.7);transform:scale(.7)}45%{-webkit-transform:scale(1.05);transform:scale(1.05)}80%{-webkit-transform:scale(.95);transform:scale(.95)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes showSweetAlert{0%{-webkit-transform:scale(.7);transform:scale(.7)}45%{-webkit-transform:scale(1.05);transform:scale(1.05)}80%{-webkit-transform:scale(.95);transform:scale(.95)}100%{-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}100%{-webkit-transform:scale(.5);transform:scale(.5);opacity:0}}@keyframes hideSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}100%{-webkit-transform:scale(.5);transform:scale(.5);opacity:0}}.show-swal2{-webkit-animation:showSweetAlert .3s;animation:showSweetAlert .3s}.show-swal2.no-animation{-webkit-animation:none;animation:none}.hide-swal2{-webkit-animation:hideSweetAlert .15s forwards;animation:hideSweetAlert .15s forwards}.hide-swal2.no-animation{-webkit-animation:none;animation:none}@-webkit-keyframes animate-success-tip{0%,54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@keyframes animate-success-tip{0%,54%{width:0;left:1px;top:19px}70%{width:50px;left:-8px;top:37px}84%{width:17px;left:21px;top:48px}100%{width:25px;left:14px;top:45px}}@-webkit-keyframes animate-success-long{0%,65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@keyframes animate-success-long{0%,65%{width:0;right:46px;top:54px}84%{width:55px;right:0;top:35px}100%{width:47px;right:8px;top:38px}}@-webkit-keyframes rotatePlaceholder{0%,5%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}100%,12%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}}@keyframes rotatePlaceholder{0%,5%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}100%,12%{-webkit-transform:rotate(-405deg);transform:rotate(-405deg)}}.animate-success-tip{-webkit-animation:animate-success-tip .75s;animation:animate-success-tip .75s}.animate-success-long{-webkit-animation:animate-success-long .75s;animation:animate-success-long .75s}.swal2-icon.swal2-success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}@-webkit-keyframes animate-error-icon{0%{-webkit-transform:rotateX(100deg);transform:rotateX(100deg);opacity:0}100%{-webkit-transform:rotateX(0);transform:rotateX(0);opacity:1}}@keyframes animate-error-icon{0%{-webkit-transform:rotateX(100deg);transform:rotateX(100deg);opacity:0}100%{-webkit-transform:rotateX(0);transform:rotateX(0);opacity:1}}.animate-error-icon{-webkit-animation:animate-error-icon .5s;animation:animate-error-icon .5s}@-webkit-keyframes animate-x-mark{0%,50%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}80%{-webkit-transform:scale(1.15);transform:scale(1.15);margin-top:-6px}100%{-webkit-transform:scale(1);transform:scale(1);margin-top:0;opacity:1}}@keyframes animate-x-mark{0%,50%{-webkit-transform:scale(.4);transform:scale(.4);margin-top:26px;opacity:0}80%{-webkit-transform:scale(1.15);transform:scale(1.15);margin-top:-6px}100%{-webkit-transform:scale(1);transform:scale(1);margin-top:0;opacity:1}}.animate-x-mark{-webkit-animation:animate-x-mark .5s;animation:animate-x-mark .5s}@-webkit-keyframes pulse-warning{0%{border-color:#f8d486}100%{border-color:#f8bb86}}@keyframes pulse-warning{0%{border-color:#f8d486}100%{border-color:#f8bb86}}.pulse-warning{-webkit-animation:pulse-warning .75s infinite alternate;animation:pulse-warning .75s infinite alternate}@-webkit-keyframes rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}
|
database_basics_data.php
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
<?php
|
|
|
2 |
$internetCountryCodes = array(
|
3 |
'A1' => 'Anonymous Proxy', 'A2' => 'Satellite Provider', 'O1' => 'Other Country', 'AD' => 'Andorra',
|
4 |
'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla',
|
@@ -153,7 +154,7 @@ $contriesLatLng = array(
|
|
153 |
'ZA' => array('-29.0000', '24.0000'), 'ZM' => array('-15.0000', '30.0000'), 'ZR' => array('-4.038333', '21.758664'),
|
154 |
'ZW' => array('-20.0000', '30.0000')
|
155 |
);
|
156 |
-
|
157 |
$searchEngines = array(
|
158 |
array('srh_name' => 'Google', 'srh_icon' => 'google.png', 'srh_query_parameter' => 'q', 'srh_identifier' => 'google',
|
159 |
'crawlers' => array(
|
1 |
<?php
|
2 |
+
|
3 |
$internetCountryCodes = array(
|
4 |
'A1' => 'Anonymous Proxy', 'A2' => 'Satellite Provider', 'O1' => 'Other Country', 'AD' => 'Andorra',
|
5 |
'AE' => 'United Arab Emirates', 'AF' => 'Afghanistan', 'AG' => 'Antigua and Barbuda', 'AI' => 'Anguilla',
|
154 |
'ZA' => array('-29.0000', '24.0000'), 'ZM' => array('-15.0000', '30.0000'), 'ZR' => array('-4.038333', '21.758664'),
|
155 |
'ZW' => array('-20.0000', '30.0000')
|
156 |
);
|
157 |
+
|
158 |
$searchEngines = array(
|
159 |
array('srh_name' => 'Google', 'srh_icon' => 'google.png', 'srh_query_parameter' => 'q', 'srh_identifier' => 'google',
|
160 |
'crawlers' => array(
|
functions.php
CHANGED
@@ -8,157 +8,261 @@
|
|
8 |
*
|
9 |
* @return void
|
10 |
*/
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
function ahc_getVisitsTime(){
|
39 |
-
global $wpdb;
|
40 |
-
$result = $wpdb->get_results("SELECT COUNT( `vtm_id` ) cnt FROM ahc_visits_time", OBJECT);
|
41 |
-
if($result !== false){
|
42 |
-
return $result[0]->cnt;
|
43 |
-
}
|
44 |
-
return false;
|
45 |
-
}
|
46 |
|
47 |
-
function ahc_getCountriesCount(){
|
48 |
-
global $wpdb;
|
49 |
-
$result = $wpdb->get_results("SELECT COUNT( `ctr_id` ) cnt FROM ahc_countries", OBJECT);
|
50 |
-
if($result !== false){
|
51 |
-
return $result[0]->cnt;
|
52 |
-
}
|
53 |
-
return false;
|
54 |
-
}
|
55 |
-
|
56 |
-
|
57 |
-
function ahc_set_default_options(){
|
58 |
-
// plugin activation
|
59 |
-
require_once("database_basics_data.php");
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
$plugin_options = array();
|
64 |
-
$plugin_options['ahc_version'] = '1.0';
|
65 |
-
$plugin_options['available_languages'] = array('ar' => 'عربي', 'en' => 'English');
|
66 |
-
$plugin_options['ahc_lang'] = 'en';
|
67 |
-
$plugin_options['user_roles_to_not_track'] = array('administrator' => true, 'editor' => true, 'author' => true, 'contributor' => true, 'subscriber' => false);
|
68 |
-
add_option( 'ahc_wp_hits_counter_options', $plugin_options);
|
69 |
-
set_time_limit(300);
|
70 |
-
}
|
71 |
-
ahc_create_database_tables();
|
72 |
-
|
73 |
-
if(ahc_getCountriesCount() == 0)
|
74 |
-
{
|
75 |
-
ahc_insert_countries_into_table($internetCountryCodes, $contriesLatLng);
|
76 |
-
}
|
77 |
-
|
78 |
-
if(ahc_search_engins_count() == 0)
|
79 |
{
|
80 |
-
|
81 |
}
|
82 |
|
83 |
-
if(ahc_browsers_count() == 0)
|
84 |
-
{
|
85 |
-
ahc_insert_browsers_into_table($browsers);
|
86 |
-
}
|
87 |
|
88 |
-
if(ahc_getVisitsTime() == 0)
|
89 |
-
{
|
90 |
-
ahc_insert_visit_times_into_table($dayHours);
|
91 |
-
}
|
92 |
|
|
|
93 |
|
|
|
94 |
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
}
|
97 |
|
98 |
-
|
|
|
|
|
|
|
|
|
99 |
global $wpdb;
|
100 |
-
$
|
101 |
-
$
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
-
|
122 |
}
|
123 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
|
126 |
-
function
|
127 |
global $wpdb;
|
128 |
-
$
|
129 |
-
$
|
130 |
-
$
|
131 |
-
$
|
132 |
-
$
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
}
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
}
|
148 |
-
|
149 |
}
|
150 |
-
return '['.$x.']';
|
151 |
-
}
|
152 |
|
153 |
|
|
|
|
|
|
|
154 |
//--------------------------------------------
|
155 |
/**
|
156 |
* Called when plugin is deactivated
|
157 |
*
|
158 |
* @return void
|
159 |
*/
|
160 |
-
function
|
|
|
161 |
}
|
|
|
162 |
//--------------------------------------------
|
163 |
/**
|
164 |
* Creates plugin page link in the admin menu
|
@@ -168,20 +272,158 @@ function ahc_unset_default_options(){
|
|
168 |
*
|
169 |
* @return void
|
170 |
*/
|
171 |
-
function
|
172 |
-
|
173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
}
|
|
|
175 |
//--------------------------------------------
|
176 |
/**
|
177 |
* Creates the main overview page
|
178 |
*
|
179 |
* @return void
|
180 |
*/
|
181 |
-
function
|
182 |
-
|
183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
}
|
|
|
185 |
//--------------------------------------------
|
186 |
/**
|
187 |
* Returns links array of available languages
|
@@ -191,21 +433,22 @@ function ahc_create_plugin_overview_page(){
|
|
191 |
*
|
192 |
* @return array
|
193 |
*/
|
194 |
-
function
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
}
|
|
|
209 |
//--------------------------------------------
|
210 |
/**
|
211 |
* Decides whether or not should track the current visitor
|
@@ -215,23 +458,24 @@ function ahc_get_change_lang_links(){
|
|
215 |
*
|
216 |
* @return boolean
|
217 |
*/
|
218 |
-
function
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
}
|
|
|
235 |
//--------------------------------------------
|
236 |
/**
|
237 |
* Returns true if the current user has administrator role
|
@@ -241,162 +485,173 @@ function ahc_should_track_visitor(){
|
|
241 |
*
|
242 |
* @return boolean
|
243 |
*/
|
244 |
-
function
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
}
|
|
|
260 |
//--------------------------------------------
|
261 |
/**
|
262 |
-
*
|
263 |
*
|
264 |
* @uses wpdb::query()
|
265 |
*
|
266 |
* @return boolean
|
267 |
*/
|
268 |
-
|
269 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
270 |
global $wpdb;
|
271 |
$sqlQueries = array();
|
272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
(
|
274 |
-
`
|
275 |
-
PRIMARY KEY(`
|
276 |
`hit_ip_address` VARCHAR(50) NOT NULL,
|
277 |
-
`hit_user_agent` VARCHAR(200) NOT NULL,
|
278 |
-
`hit_request_uri` VARCHAR(200) NULL,
|
279 |
`hit_page_id` VARCHAR(30) NOT NULL,
|
280 |
-
`
|
281 |
-
`hit_referer` VARCHAR(300) NULL,
|
282 |
-
`hit_referer_site` VARCHAR(100) NULL,
|
283 |
-
`srh_id` INT(3) UNSIGNED NULL,
|
284 |
-
`hit_search_words` VARCHAR(200) NULL,
|
285 |
-
`bsr_id` INT(3) UNSIGNED NOT NULL,
|
286 |
-
`hit_date` DATE NOT NULL,
|
287 |
-
`hit_time` TIME NOT NULL
|
288 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
289 |
-
|
290 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_browsers`
|
291 |
-
(
|
292 |
-
`bsr_id` INT(3) UNSIGNED NOT NULL,
|
293 |
-
PRIMARY KEY(`bsr_id`),
|
294 |
-
`bsr_name` VARCHAR(100) NOT NULL,
|
295 |
-
`bsr_icon` VARCHAR(50),
|
296 |
-
`bsr_visits` INT(11) NOT NULL DEFAULT 0
|
297 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
298 |
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
`srh_query_parameter` VARCHAR(10) NOT NULL,
|
305 |
-
`srh_icon` VARCHAR(50),
|
306 |
-
`srh_identifier` VARCHAR(50)
|
307 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
308 |
-
|
309 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_search_engine_crawlers`
|
310 |
-
(
|
311 |
-
`bot_name` VARCHAR(50) NOT NULL,
|
312 |
-
`srh_id` INT(3) UNSIGNED NOT NULL
|
313 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
314 |
-
|
315 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_visitors`
|
316 |
-
(
|
317 |
-
`vst_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
318 |
-
PRIMARY KEY (`vst_id`),
|
319 |
-
`vst_date` DATE NOT NULL,
|
320 |
-
`vst_visitors` INT(11) UNSIGNED NULL DEFAULT 0,
|
321 |
-
`vst_visits` INT(11) UNSIGNED NULL DEFAULT 0
|
322 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
323 |
-
|
324 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_searching_visits`
|
325 |
-
(
|
326 |
-
`vtsh_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
327 |
-
PRIMARY KEY (`vtsh_id`),
|
328 |
-
`srh_id` INT(3) UNSIGNED NOT NULL,
|
329 |
-
`vtsh_date` DATE NOT NULL,
|
330 |
-
`vtsh_visits` INT(11) UNSIGNED NOT NULL DEFAULT 0
|
331 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
332 |
-
|
333 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_refering_sites`
|
334 |
-
(
|
335 |
-
`rfr_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
336 |
-
PRIMARY KEY (`rfr_id`),
|
337 |
-
`rfr_site_name` VARCHAR(100) NOT NULL,
|
338 |
-
`rfr_visits` INT(11) UNSIGNED NULL DEFAULT 0
|
339 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
340 |
-
|
341 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_recent_visitors`
|
342 |
-
(
|
343 |
-
`vtr_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
344 |
-
PRIMARY KEY (`vtr_id`),
|
345 |
-
`vtr_ip_address` VARCHAR(50) NOT NULL,
|
346 |
-
`vtr_referer` VARCHAR(300) NULL,
|
347 |
-
`srh_id` INT(3) UNSIGNED NULL,
|
348 |
-
`bsr_id` INT(3) UNSIGNED NOT NULL,
|
349 |
-
`vtr_date` DATE NOT NULL,
|
350 |
-
`vtr_time` TIME NOT NULL
|
351 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
352 |
-
|
353 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_keywords`
|
354 |
-
(
|
355 |
-
`kwd_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
356 |
-
PRIMARY KEY (`kwd_id`),
|
357 |
-
`kwd_ip_address` VARCHAR(50) NOT NULL,
|
358 |
-
`kwd_keywords` VARCHAR(200) NOT NULL,
|
359 |
-
`kwd_referer` VARCHAR(300) NOT NULL,
|
360 |
-
`srh_id` INT(3) UNSIGNED NOT NULL,
|
361 |
-
`bsr_id` INT(3) UNSIGNED NOT NULL,
|
362 |
-
`kwd_date` DATE NOT NULL,
|
363 |
-
`kwd_time` TIME NOT NULL
|
364 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
365 |
-
|
366 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_title_traffic`
|
367 |
-
(
|
368 |
-
`til_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
369 |
-
PRIMARY KEY (`til_id`),
|
370 |
-
`til_page_id` VARCHAR(30) NOT NULL,
|
371 |
-
`til_page_title` VARCHAR(100),
|
372 |
-
`til_hits` INT(11) UNSIGNED NOT NULL
|
373 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
374 |
-
|
375 |
-
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_visits_time`
|
376 |
-
(
|
377 |
-
`vtm_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
378 |
-
PRIMARY KEY (`vtm_id`),
|
379 |
-
`vtm_time_from` TIME NOT NULL,
|
380 |
-
`vtm_time_to` TIME NOT NULL,
|
381 |
-
`vtm_visitors` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
382 |
-
`vtm_visits` INT(11) UNSIGNED NOT NULL DEFAULT 0
|
383 |
-
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
384 |
-
|
385 |
-
foreach($sqlQueries as $sql){
|
386 |
-
if($wpdb->query($sql) === false){
|
387 |
-
return false;
|
388 |
-
}
|
389 |
}
|
390 |
-
return true;
|
391 |
}
|
392 |
-
*/
|
393 |
|
|
|
394 |
|
|
|
|
|
395 |
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
400 |
(
|
401 |
`hit_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
402 |
PRIMARY KEY(`hit_id`),
|
@@ -414,8 +669,24 @@ function ahc_create_database_tables(){
|
|
414 |
`hit_date` DATE NOT NULL,
|
415 |
`hit_time` TIME NOT NULL
|
416 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
417 |
-
|
418 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
419 |
(
|
420 |
`bsr_id` INT(3) UNSIGNED NOT NULL,
|
421 |
PRIMARY KEY(`bsr_id`),
|
@@ -423,8 +694,8 @@ function ahc_create_database_tables(){
|
|
423 |
`bsr_icon` VARCHAR(50),
|
424 |
`bsr_visits` INT(11) NOT NULL DEFAULT 0
|
425 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
426 |
-
|
427 |
-
|
428 |
(
|
429 |
`srh_id` INT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
|
430 |
PRIMARY KEY(`srh_id`),
|
@@ -433,14 +704,14 @@ function ahc_create_database_tables(){
|
|
433 |
`srh_icon` VARCHAR(50),
|
434 |
`srh_identifier` VARCHAR(50)
|
435 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
436 |
-
|
437 |
-
|
438 |
(
|
439 |
`bot_name` VARCHAR(50) NOT NULL,
|
440 |
`srh_id` INT(3) UNSIGNED NOT NULL
|
441 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
442 |
-
|
443 |
-
|
444 |
(
|
445 |
`ctr_id` INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
|
446 |
PRIMARY KEY(`ctr_id`),
|
@@ -451,8 +722,8 @@ function ahc_create_database_tables(){
|
|
451 |
`ctr_visitors` INT(11) NOT NULL DEFAULT 0,
|
452 |
`ctr_visits` INT(11) NOT NULL DEFAULT 0
|
453 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
454 |
-
|
455 |
-
|
456 |
(
|
457 |
`vst_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
458 |
PRIMARY KEY (`vst_id`),
|
@@ -460,8 +731,20 @@ function ahc_create_database_tables(){
|
|
460 |
`vst_visitors` INT(11) UNSIGNED NULL DEFAULT 0,
|
461 |
`vst_visits` INT(11) UNSIGNED NULL DEFAULT 0
|
462 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
463 |
-
|
464 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
(
|
466 |
`vtsh_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
467 |
PRIMARY KEY (`vtsh_id`),
|
@@ -469,16 +752,18 @@ function ahc_create_database_tables(){
|
|
469 |
`vtsh_date` DATE NOT NULL,
|
470 |
`vtsh_visits` INT(11) UNSIGNED NOT NULL DEFAULT 0
|
471 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
472 |
-
|
473 |
-
|
|
|
|
|
474 |
(
|
475 |
`rfr_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
476 |
PRIMARY KEY (`rfr_id`),
|
477 |
`rfr_site_name` VARCHAR(100) NOT NULL,
|
478 |
`rfr_visits` INT(11) UNSIGNED NULL DEFAULT 0
|
479 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
480 |
-
|
481 |
-
|
482 |
(
|
483 |
`vtr_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
484 |
PRIMARY KEY (`vtr_id`),
|
@@ -490,8 +775,8 @@ function ahc_create_database_tables(){
|
|
490 |
`vtr_date` DATE NOT NULL,
|
491 |
`vtr_time` TIME NOT NULL
|
492 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
493 |
-
|
494 |
-
|
495 |
(
|
496 |
`kwd_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
497 |
PRIMARY KEY (`kwd_id`),
|
@@ -504,8 +789,8 @@ function ahc_create_database_tables(){
|
|
504 |
`kwd_date` DATE NOT NULL,
|
505 |
`kwd_time` TIME NOT NULL
|
506 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
507 |
-
|
508 |
-
|
509 |
(
|
510 |
`til_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
511 |
PRIMARY KEY (`til_id`),
|
@@ -513,8 +798,8 @@ function ahc_create_database_tables(){
|
|
513 |
`til_page_title` VARCHAR(100),
|
514 |
`til_hits` INT(11) UNSIGNED NOT NULL
|
515 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
516 |
-
|
517 |
-
|
518 |
(
|
519 |
`vtm_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
520 |
PRIMARY KEY (`vtm_id`),
|
@@ -523,120 +808,126 @@ function ahc_create_database_tables(){
|
|
523 |
`vtm_visitors` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
524 |
`vtm_visits` INT(11) UNSIGNED NOT NULL DEFAULT 0
|
525 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
533 |
}
|
|
|
534 |
//--------------------------------------------
|
535 |
/**
|
536 |
-
* Inserts
|
537 |
*
|
538 |
* @uses wpdb::insert()
|
539 |
-
* @uses wpdb::$insert_id
|
540 |
*
|
541 |
-
* @param array $
|
|
|
542 |
* @return boolean
|
543 |
*/
|
544 |
-
function
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
if($result2 === false){
|
569 |
-
return false;
|
570 |
-
}
|
571 |
-
}
|
572 |
-
} else{
|
573 |
-
return false;
|
574 |
-
}
|
575 |
-
}
|
576 |
-
return true;
|
577 |
}
|
|
|
578 |
//--------------------------------------------
|
579 |
/**
|
580 |
-
* Inserts
|
581 |
*
|
582 |
* @uses wpdb::insert()
|
|
|
583 |
*
|
584 |
-
* @param array $
|
585 |
* @return boolean
|
586 |
*/
|
587 |
-
function
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
604 |
}
|
605 |
|
|
|
606 |
/**
|
607 |
-
* Inserts
|
608 |
*
|
609 |
* @uses wpdb::insert()
|
610 |
*
|
611 |
-
* @param array $
|
612 |
-
* @param array $contriesLatLng. LatLng of countries
|
613 |
* @return boolean
|
614 |
*/
|
615 |
-
function
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
array(
|
632 |
-
'%s', '%s', '%s', '%s'
|
633 |
-
)
|
634 |
-
);
|
635 |
-
if($result === false){
|
636 |
-
return false;
|
637 |
-
}
|
638 |
-
}
|
639 |
-
return true;
|
640 |
}
|
641 |
|
642 |
//--------------------------------------------
|
@@ -648,24 +939,24 @@ function ahc_insert_countries_into_table($internetCountryCodes, $contriesLatLng)
|
|
648 |
* @param array $dayHours
|
649 |
* @return boolean
|
650 |
*/
|
651 |
-
function
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
return true;
|
668 |
}
|
|
|
669 |
//--------------------------------------------
|
670 |
/**
|
671 |
* Returns the first and last days of the week of the date you pass
|
@@ -674,117 +965,130 @@ function ahc_insert_visit_times_into_table($dayHours){
|
|
674 |
* @param string $format Optional
|
675 |
* @return array
|
676 |
*/
|
677 |
-
function
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
713 |
}
|
|
|
714 |
//--------------------------------------------
|
715 |
/**
|
716 |
* Return summary statistics of visitors and visits
|
717 |
*
|
718 |
* @return array
|
719 |
*/
|
720 |
-
function
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
}
|
|
|
730 |
//--------------------------------------------
|
731 |
/**
|
732 |
* Return counts visitors and visits in certain day (today|yesterday), certain period(last week, last month, last year) or total
|
733 |
*
|
734 |
* @uses wpdb::prepare()
|
735 |
-
* @uses wpdb::get_results()
|
736 |
-
*
|
737 |
-
* @param string $period Optional
|
738 |
-
* @return mixed
|
739 |
-
*/
|
740 |
-
function
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
|
|
|
|
|
|
|
|
787 |
}
|
|
|
788 |
//--------------------------------------------
|
789 |
/**
|
790 |
* Return visits in a period from today
|
@@ -794,93 +1098,108 @@ function ahc_get_visitors_visits_in_period($period = 'total'){
|
|
794 |
*
|
795 |
* @return array
|
796 |
*/
|
797 |
-
function
|
798 |
global $wpdb;
|
799 |
$lastDays = AHC_VISITORS_VISITS_LIMIT - 1;
|
800 |
$response = array();
|
|
|
|
|
801 |
$beginning = new DateTime();
|
802 |
-
$beginning->
|
803 |
-
$
|
|
|
|
|
804 |
FROM ahc_visitors
|
805 |
-
WHERE DATE(vst_date) >= DATE(%s)";
|
806 |
-
|
807 |
-
|
808 |
$results = $wpdb->get_results($wpdb->prepare($sql, $beginning->format('Y-m-d')), OBJECT);
|
809 |
-
if($results !== false){
|
810 |
$response['success'] = true;
|
811 |
$response['date'] = array();
|
812 |
-
for($i = count($results); $i < $lastDays; $i++){
|
813 |
$beginning->modify('+1 day');
|
814 |
$response['data']['dates'][] = $beginning->format('d/m');
|
815 |
$response['data']['visitors'][] = 0;
|
816 |
$response['data']['visits'][] = 0;
|
817 |
}
|
818 |
-
|
|
|
819 |
$hitDate = new DateTime($r->vst_date);
|
|
|
820 |
$response['data']['dates'][] = $hitDate->format('d/m');
|
821 |
$response['data']['visitors'][] = $r->vst_visitors;
|
822 |
$response['data']['visits'][] = $r->vst_visits;
|
823 |
}
|
824 |
-
} else{
|
825 |
$response['success'] = false;
|
826 |
}
|
827 |
return $response;
|
828 |
}
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
883 |
}
|
|
|
|
|
|
|
884 |
//--------------------------------------------
|
885 |
/**
|
886 |
* Returns the total visits by search engines
|
@@ -889,14 +1208,15 @@ function ahc_get_serch_visits_by_date(){
|
|
889 |
*
|
890 |
* @return mixed
|
891 |
*/
|
892 |
-
function
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
}
|
|
|
900 |
//--------------------------------------------
|
901 |
/**
|
902 |
* Return counts visits happened by search engine result in certain day (today|yesterday), certain period(last week, last month, last year) or total
|
@@ -907,53 +1227,56 @@ function ahc_get_total_visits_by_search_engines(){
|
|
907 |
* @param string $period Optional
|
908 |
* @return mixed
|
909 |
*/
|
910 |
-
function
|
911 |
-
|
912 |
-
|
913 |
-
|
|
|
|
|
|
|
914 |
FROM `ahc_searching_visits`";
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
return false;
|
956 |
}
|
|
|
957 |
//--------------------------------------------
|
958 |
/**
|
959 |
* Retrieves all search engines
|
@@ -962,23 +1285,24 @@ function ahc_get_hits_search_engines_referers($period = 'total'){
|
|
962 |
*
|
963 |
* @return mixed
|
964 |
*/
|
965 |
-
function
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
}
|
|
|
982 |
//--------------------------------------------
|
983 |
/**
|
984 |
* Retrieves count of visits order by browsers
|
@@ -987,28 +1311,66 @@ function ahc_get_all_search_engines(){
|
|
987 |
*
|
988 |
* @return array
|
989 |
*/
|
990 |
-
function
|
991 |
-
|
992 |
-
|
993 |
FROM `ahc_browsers`
|
994 |
WHERE `bsr_visits` > 0";
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1011 |
}
|
|
|
1012 |
//--------------------------------------------
|
1013 |
/**
|
1014 |
* Retrieves top referring sites
|
@@ -1018,26 +1380,104 @@ function ahc_get_browsers_hits_counts(){
|
|
1018 |
*
|
1019 |
* @return mixed
|
1020 |
*/
|
1021 |
-
function
|
1022 |
-
|
1023 |
-
|
1024 |
FROM `ahc_refering_sites`
|
1025 |
ORDER BY rfr_visits DESC
|
1026 |
LIMIT %d OFFSET 0";
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1040 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1041 |
//--------------------------------------------
|
1042 |
/**
|
1043 |
* Retrieves recent visitors
|
@@ -1047,37 +1487,56 @@ function ahc_get_top_refering_sites(){
|
|
1047 |
*
|
1048 |
* @return mixed
|
1049 |
*/
|
1050 |
-
function
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
|
|
1054 |
FROM `ahc_recent_visitors` AS v
|
1055 |
-
JOIN `
|
|
|
1056 |
WHERE v.vtr_ip_address NOT LIKE 'UNKNOWN%%'
|
1057 |
-
ORDER BY v.
|
1058 |
-
LIMIT
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1080 |
}
|
|
|
1081 |
//--------------------------------------------
|
1082 |
/**
|
1083 |
* Retrieves latest of key words used in search
|
@@ -1087,47 +1546,138 @@ function ahc_get_recent_visitors(){
|
|
1087 |
*
|
1088 |
* @return mixed
|
1089 |
*/
|
1090 |
-
function
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
|
|
1094 |
FROM `ahc_keywords` AS k
|
|
|
1095 |
JOIN `ahc_browsers` AS b ON k.bsr_id = b.bsr_id
|
1096 |
JOIN `ahc_search_engines` AS s on k.srh_id = s.srh_id
|
1097 |
-
WHERE k.kwd_ip_address
|
1098 |
ORDER BY k.kwd_date DESC, k.kwd_time DESC
|
1099 |
LIMIT %d OFFSET 0";
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
|
|
|
|
|
|
1121 |
}
|
|
|
1122 |
//--------------------------------------------
|
1123 |
/**
|
1124 |
* Is in login page
|
1125 |
*
|
1126 |
* @return boolean
|
1127 |
*/
|
1128 |
-
function
|
1129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1130 |
}
|
|
|
1131 |
//--------------------------------------------
|
1132 |
/**
|
1133 |
* Detect if the visitor is search engine bot
|
@@ -1135,42 +1685,44 @@ function ahc_is_login_page() {
|
|
1135 |
* @uses wpdb::get_results()
|
1136 |
*
|
1137 |
* @return boolean
|
1138 |
-
*/
|
1139 |
-
function
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
}
|
|
|
1161 |
//--------------------------------------------
|
1162 |
/**
|
1163 |
* Detect if the visitor is WordPress bot
|
1164 |
*
|
1165 |
* @return boolean
|
1166 |
*/
|
1167 |
-
function
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
}
|
|
|
1174 |
//--------------------------------------------
|
1175 |
/**
|
1176 |
* Detects post id, post title and post type of current page
|
@@ -1181,71 +1733,105 @@ function ahc_is_wordpress_bot(){
|
|
1181 |
* @param object $query. this object is passed to the callback function of "parse_query" hooked action
|
1182 |
* @return mixed
|
1183 |
*/
|
1184 |
-
function
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
$result = $wpdb->get_results($wpdb->prepare("SELECT post_title FROM ".$wpdb->prefix."posts WHERE ID = %s AND post_type = %s", $vars['page_id'], 'page'));
|
1211 |
-
if($result !== false && $wpdb->num_rows > 0){
|
1212 |
-
return array('page_id' => $page_id, 'page_title' => $result[0]->post_title, 'post_type' => 'page');
|
1213 |
-
}
|
1214 |
-
}
|
1215 |
-
|
1216 |
-
else{
|
1217 |
-
return array('page_id' => 'HOMEPAGE', 'page_title' => NULL, 'post_type' => NULL);
|
1218 |
-
}
|
1219 |
}
|
1220 |
|
1221 |
-
function
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
}
|
|
|
1228 |
//--------------------------------------------
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1248 |
}
|
|
|
|
|
|
|
1249 |
//--------------------------------------------
|
1250 |
/**
|
1251 |
* Ceil for decimal numbers with precision
|
@@ -1255,20 +1841,22 @@ function ahc_track_visitor($query){
|
|
1255 |
* @param string $separator
|
1256 |
* @return float
|
1257 |
*/
|
1258 |
-
function
|
1259 |
-
|
1260 |
-
|
1261 |
-
$numberpart[1]=substr_replace($numberpart[1]
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
|
|
1271 |
}
|
|
|
1272 |
//--------------------------------------------
|
1273 |
/**
|
1274 |
* Retrieve sum visits by post title
|
@@ -1278,42 +1866,43 @@ $numberpart[1]=substr_replace($numberpart[1],$separator,$precision,0);
|
|
1278 |
*
|
1279 |
* @return mixed
|
1280 |
*/
|
1281 |
-
function
|
1282 |
-
|
1283 |
-
|
1284 |
SELECT SUM(til_hits) AS hits
|
1285 |
FROM ahc_title_traffic
|
1286 |
GROUP BY til_page_id
|
1287 |
) myTable";
|
1288 |
-
|
1289 |
-
|
1290 |
FROM ahc_title_traffic
|
1291 |
GROUP BY til_page_id
|
1292 |
ORDER BY til_hits DESC
|
1293 |
LIMIT %d OFFSET 0";
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
}
|
|
|
1317 |
//--------------------------------------------
|
1318 |
/**
|
1319 |
* Retrieves sum of visits order by time
|
@@ -1322,71 +1911,147 @@ function ahc_get_traffic_by_title(){
|
|
1322 |
*
|
1323 |
* @return mixed
|
1324 |
*/
|
1325 |
-
function
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
$
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
$
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
$
|
1349 |
-
|
1350 |
-
|
1351 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1352 |
}
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1357 |
}
|
|
|
1358 |
//--------------------------------------------
|
1359 |
/**
|
1360 |
* Returns client IP address
|
1361 |
*
|
1362 |
* @return string
|
1363 |
*/
|
1364 |
-
function
|
1365 |
-
|
1366 |
-
|
1367 |
-
if(isset($_SERVER['
|
|
|
|
|
1368 |
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
|
1369 |
-
|
1370 |
-
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
|
1371 |
$ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
1372 |
-
|
1373 |
-
else if(isset($_SERVER['HTTP_X_FORWARDED']) && !empty($_SERVER['HTTP_X_FORWARDED'])){
|
1374 |
$ipAddress = $_SERVER['HTTP_X_FORWARDED'];
|
1375 |
-
|
1376 |
-
else if(isset($_SERVER['HTTP_FORWARDED_FOR']) && !empty($_SERVER['HTTP_FORWARDED_FOR'])){
|
1377 |
$ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
|
1378 |
-
|
1379 |
-
else if(isset($_SERVER['HTTP_FORWARDED']) && !empty($_SERVER['HTTP_FORWARDED'])){
|
1380 |
$ipAddress = $_SERVER['HTTP_FORWARDED'];
|
1381 |
-
|
1382 |
-
else if(isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR'])){
|
1383 |
-
$ipAddress = $_SERVER['REMOTE_ADDR'];
|
1384 |
-
}
|
1385 |
-
else{
|
1386 |
$ipAddress = 'UNKNOWN';
|
1387 |
-
|
1388 |
-
|
|
|
|
|
|
|
1389 |
}
|
|
|
1390 |
//--------------------------------------------
|
1391 |
/**
|
1392 |
* To include scripts and styles tags into the head
|
@@ -1398,117 +2063,501 @@ function ahc_get_client_ip_address(){
|
|
1398 |
*
|
1399 |
* @return void
|
1400 |
*/
|
1401 |
-
function
|
1402 |
-
wp_register_style('ahc_lang_css', plugins_url('/css/en_newcss.css', AHC_PLUGIN_MAIN_FILE));
|
1403 |
-
wp_enqueue_style('ahc_lang_css');
|
1404 |
-
|
1405 |
-
wp_register_style('ahc_bootstrap_css', plugins_url('/lib/bootstrap/css/bootstrap.min.css', AHC_PLUGIN_MAIN_FILE));
|
1406 |
-
wp_enqueue_style('ahc_bootstrap_css');
|
1407 |
-
|
1408 |
-
wp_enqueue_script('jquery');
|
1409 |
-
|
1410 |
-
wp_register_script('ahc_bootstrap_js', plugins_url('/lib/bootstrap/js/bootstrap.min.js', AHC_PLUGIN_MAIN_FILE));
|
1411 |
-
wp_enqueue_script('ahc_bootstrap_js');
|
1412 |
-
|
1413 |
-
wp_register_script('ahc_lang_js', plugins_url('/lang/js/'.Globals::$lang.'_lang.js', AHC_PLUGIN_MAIN_FILE));
|
1414 |
-
wp_enqueue_script('ahc_lang_js');
|
1415 |
-
|
1416 |
-
wp_register_script('ahc_main_js', plugins_url('/js/js.js', AHC_PLUGIN_MAIN_FILE));
|
1417 |
-
wp_enqueue_script('ahc_main_js');
|
1418 |
-
|
1419 |
-
|
1420 |
-
wp_register_script('ahc_Chart_js', plugins_url('/lib/Chart_js/Chart.min.js', AHC_PLUGIN_MAIN_FILE));
|
1421 |
-
wp_enqueue_script('ahc_Chart_js');
|
1422 |
-
|
1423 |
-
wp_register_script('ahc_google_maps', 'http://maps.googleapis.com/maps/api/js?key=AIzaSyB0fRgC_3Wmp1PY5ZsuzK8VEooiUvVQq3Q&sensor=false');
|
1424 |
-
wp_enqueue_script('ahc_google_maps');
|
1425 |
-
|
1426 |
|
1427 |
|
1428 |
-
|
1429 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1430 |
|
|
|
|
|
1431 |
|
|
|
|
|
1432 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1433 |
//---------------------------------------------Add button to the admin bar
|
1434 |
-
function
|
1435 |
-
|
1436 |
-
global $pluginsurl;
|
1437 |
|
1438 |
-
$wccpadminurl = get_admin_url();
|
1439 |
//The properties of the new item. Read More about the missing 'parent' parameter below
|
1440 |
$args = array(
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
//This is where the magic works.
|
1448 |
-
$admin_bar->add_menu(
|
1449 |
}
|
|
|
1450 |
//---------------------------------------- Add plugin settings link to Plugins page
|
1451 |
-
function
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
}
|
|
|
1456 |
//------------------------------------------------------------------------
|
|
|
|
|
|
|
1457 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1458 |
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
|
|
|
|
|
|
|
|
1463 |
|
1464 |
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1470 |
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
});
|
1509 |
-
</script>
|
1510 |
-
|
1511 |
-
<?php
|
1512 |
}
|
1513 |
-
|
1514 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
*
|
9 |
* @return void
|
10 |
*/
|
11 |
+
function ahcfree_getVisitsTime() {
|
12 |
+
global $wpdb;
|
13 |
+
$result = $wpdb->get_results("SELECT COUNT( `vtm_id` ) cnt FROM ahc_visits_time", OBJECT);
|
14 |
+
if ($result !== false) {
|
15 |
+
return $result[0]->cnt;
|
16 |
+
}
|
17 |
+
return false;
|
18 |
+
}
|
19 |
|
20 |
+
|
21 |
+
|
22 |
+
/**
|
23 |
+
* change plugin settings
|
24 |
+
* @return void
|
25 |
+
*/
|
26 |
+
function ahcfree_savesettings() {
|
27 |
+
global $wpdb;
|
28 |
+
|
29 |
+
$set_hits_days = intval($_POST['set_hits_days']);
|
30 |
+
$set_ajax_check = 15;
|
31 |
+
$posts_type = '';
|
32 |
+
$set_ips = esc_html($_POST['set_ips']);
|
33 |
+
$set_google_map = '';
|
34 |
+
$delete_plugin_data = isset($_POST['delete_plugin_data']) ? intval($_POST['delete_plugin_data']) : '';
|
35 |
+
|
36 |
+
$custom_timezone_offset = sanitize_text_field($_POST['set_custom_timezone']);
|
37 |
+
if ($custom_timezone_offset && $custom_timezone_offset != '') {
|
38 |
+
update_option('ahcfree_custom_timezone', $custom_timezone_offset);
|
39 |
+
}
|
40 |
+
|
41 |
+
$delete_plugin_data = (isset($delete_plugin_data)) ? intval($delete_plugin_data) : 0;
|
42 |
+
update_option('ahcfree_delete_plugin_data_on_uninstall', $delete_plugin_data);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
+
$ahcUserRoles = '';
|
46 |
+
foreach ($_POST['ahcUserRoles'] as $v)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
{
|
48 |
+
$ahcUserRoles .= $v.",";
|
49 |
}
|
50 |
|
|
|
|
|
|
|
|
|
51 |
|
|
|
|
|
|
|
|
|
52 |
|
53 |
+
$wsmUserRoles = substr($ahcUserRoles,0,-1);
|
54 |
|
55 |
+
update_option('ahcUserRoles',$ahcUserRoles);
|
56 |
|
57 |
+
|
58 |
+
|
59 |
+
|
60 |
+
$sql = $wpdb->prepare("UPDATE `ahc_settings` set `set_hits_days` = %s, `set_ajax_check` = %s, `set_ips` = %s, `set_google_map` = %s ", $set_hits_days, $set_ajax_check, $set_ips, $set_google_map);
|
61 |
+
|
62 |
+
if ($wpdb->query($sql) !== false) {
|
63 |
+
|
64 |
+
return true;
|
65 |
+
}
|
66 |
+
|
67 |
+
return false;
|
68 |
}
|
69 |
|
70 |
+
|
71 |
+
|
72 |
+
|
73 |
+
|
74 |
+
function ahcfree_get_save_settings() {
|
75 |
global $wpdb;
|
76 |
+
$table_exist = ahcfree_check_table_exists('ahc_settings');
|
77 |
+
if( $table_exist ){
|
78 |
+
$result = $wpdb->get_results("SELECT set_hits_days, set_ajax_check, set_ips, set_google_map FROM ahc_settings", OBJECT);
|
79 |
+
if ($result !== false) {
|
80 |
+
return $result;
|
81 |
+
}
|
82 |
+
}
|
|
|
83 |
|
84 |
+
return false;
|
85 |
+
}
|
86 |
+
|
87 |
+
function ahcfree_get_timezone_string() {
|
88 |
+
$custom_timezone = get_option('ahcfree_custom_timezone');
|
89 |
+
if (!$custom_timezone) {
|
90 |
+
$wsmTimeZone=get_option('timezone_string' );
|
91 |
+
if(is_null($wsmTimeZone) || $wsmTimeZone==''){
|
92 |
+
$wsmTimeZone=ahcfree_GetWPTimezoneString();
|
93 |
+
}
|
94 |
+
$custom_timezone= ahcfree_CleanupTimeZoneString($wsmTimeZone);
|
95 |
+
|
96 |
+
/*
|
97 |
+
$custom_timezone = get_option( 'timezone_string' );
|
98 |
+
|
99 |
+
if ( ! empty( $custom_timezone ) ) {
|
100 |
+
return $custom_timezone;
|
101 |
}
|
102 |
+
|
103 |
+
$offset = get_option( 'gmt_offset' );
|
104 |
+
$hours = (int) $offset;
|
105 |
+
$minutes = ( $offset - floor( $offset ) ) * 60;
|
106 |
+
if( $hours < 10 ){
|
107 |
+
$hours = '0'+$hours;
|
108 |
+
}
|
109 |
+
echo $custom_timezone = sprintf( '%s:%s', $hours, $minutes );*/
|
110 |
+
|
111 |
+
}
|
112 |
+
return $custom_timezone;
|
113 |
+
}
|
114 |
+
|
115 |
+
|
116 |
+
function ahcfree_CleanupTimeZoneString($tzString){
|
117 |
+
$offset=$tzString;
|
118 |
+
|
119 |
+
if (preg_match('/^UTC[+-]/', $tzString)) {
|
120 |
+
$tzString= preg_replace('/UTC\+?/', '', $tzString);
|
121 |
+
}
|
122 |
+
if(is_numeric($tzString)){
|
123 |
+
$offset=sprintf('%02d:%02d', (int) $tzString, fmod(abs($tzString), 1) * 60);
|
124 |
+
if((int) $tzString>0){
|
125 |
+
$offset='+'.$offset;
|
126 |
}
|
|
|
127 |
}
|
128 |
+
return $offset;
|
129 |
+
}
|
130 |
+
function ahcfree_GetWPTimezoneString() {
|
131 |
+
// if site timezone string exists, return it
|
132 |
+
if ( $timezone = get_option( 'timezone_string' ) )
|
133 |
+
return $timezone;
|
134 |
+
|
135 |
+
// get UTC offset, if it isn't set then return UTC
|
136 |
+
if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) )
|
137 |
+
return 'UTC';
|
138 |
+
|
139 |
+
// adjust UTC offset from hours to seconds
|
140 |
+
$utc_offset *= 3600;
|
141 |
+
|
142 |
+
// attempt to guess the timezone string from the UTC offset
|
143 |
+
if ( $timezone = timezone_name_from_abbr( '', $utc_offset, 0 ) ) {
|
144 |
+
return $timezone;
|
145 |
+
}
|
146 |
+
|
147 |
+
// last try, guess timezone string manually
|
148 |
+
$is_dst = date( 'I' );
|
149 |
+
|
150 |
+
foreach ( timezone_abbreviations_list() as $abbr ) {
|
151 |
+
foreach ( $abbr as $city ) {
|
152 |
+
if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset )
|
153 |
+
return $city['timezone_id'];
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
// fallback to UTC
|
158 |
+
return 'UTC';
|
159 |
+
}
|
160 |
+
|
161 |
+
function ahcfree_get_current_timezone_offset() {
|
162 |
+
$tz = ahcfree_get_timezone_string();
|
163 |
+
try {
|
164 |
+
$timeZone = new DateTimeZone($tz);
|
165 |
+
$date = new DateTime('now', $timeZone);
|
166 |
+
$date->setTimezone($timeZone);
|
167 |
+
} catch (Exception $e) {
|
168 |
+
$date = new DateTime('now');
|
169 |
+
}
|
170 |
+
return '+00:00';
|
171 |
+
// return $date->format('P');
|
172 |
}
|
173 |
|
174 |
+
function ahcfree_last_hit_date() {
|
175 |
global $wpdb;
|
176 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
177 |
+
$sql = "SELECT max(CONVERT_TZ(vtr_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) as last_date FROM ahc_recent_visitors";
|
178 |
+
//echo $sql = "SELECT max(vtr_date)) as last_date FROM ahc_recent_visitors";
|
179 |
+
$result = $wpdb->get_results($sql, OBJECT);
|
180 |
+
if ($result !== false) {
|
181 |
+
return $result[0]->last_date;
|
182 |
+
}
|
183 |
+
return date('Y-m-d', time());
|
184 |
+
}
|
185 |
+
|
186 |
+
function ahcfree_getCountriesCount() {
|
187 |
+
global $wpdb;
|
188 |
+
$result = $wpdb->get_results("SELECT COUNT( `ctr_id` ) cnt FROM ahc_countries", OBJECT);
|
189 |
+
if ($result !== false) {
|
190 |
+
return $result[0]->cnt;
|
191 |
+
}
|
192 |
+
return false;
|
193 |
+
}
|
194 |
+
|
195 |
+
function ahcfree_getBrowsersCount() {
|
196 |
+
global $wpdb;
|
197 |
+
$result = $wpdb->get_results("SELECT COUNT( `bsr_id` ) cnt FROM ahc_browsers", OBJECT);
|
198 |
+
if ($result !== false) {
|
199 |
+
return $result[0]->cnt;
|
200 |
+
}
|
201 |
+
return false;
|
202 |
+
}
|
203 |
+
|
204 |
+
function ahcfree_getSearchEnginesCount() {
|
205 |
+
global $wpdb;
|
206 |
+
$result = $wpdb->get_results("SELECT COUNT( `srh_id` ) cnt FROM ahc_search_engines", OBJECT);
|
207 |
+
if ($result !== false) {
|
208 |
+
return $result[0]->cnt;
|
209 |
+
}
|
210 |
+
return false;
|
211 |
+
}
|
212 |
+
|
213 |
+
function ahcfree_set_default_options() {
|
214 |
+
// plugin activation
|
215 |
+
|
216 |
+
require_once("database_basics_data.php");
|
217 |
+
if (get_option('ahcfree_wp_hits_counter_options') === false) {
|
218 |
+
|
219 |
+
|
220 |
+
$plugin_options = array();
|
221 |
+
$plugin_options['ahcfree_version'] = '1.0';
|
222 |
+
$plugin_options['available_languages'] = array('ar' => 'عربي', 'en' => 'English');
|
223 |
+
$plugin_options['ahcfree_lang'] = 'en';
|
224 |
+
$plugin_options['user_roles_to_not_track'] = array('administrator' => true, 'editor' => true, 'author' => true, 'contributor' => true, 'subscriber' => false);
|
225 |
+
add_option('ahcfree_wp_hits_counter_options', $plugin_options);
|
226 |
+
}
|
227 |
+
set_time_limit(300);
|
228 |
+
if (ahcfree_create_database_tables()) {
|
229 |
+
|
230 |
+
if (ahcfree_getVisitsTime() > 25) {
|
231 |
+
global $wpdb;
|
232 |
+
$result = $wpdb->get_results("DELETE FROM ahc_visits_time where `vtm_id` > 24", OBJECT);
|
233 |
}
|
234 |
+
|
235 |
+
if (ahcfree_getCountriesCount() == 0) {
|
236 |
+
ahcfree_insert_countries_into_table($internetCountryCodes, $contriesLatLng);
|
237 |
+
}
|
238 |
+
|
239 |
+
if (ahcfree_getVisitsTime() == 0) {
|
240 |
+
ahcfree_insert_visit_times_into_table($dayHours);
|
241 |
+
}
|
242 |
+
|
243 |
+
if (ahcfree_getSearchEnginesCount() == 0) {
|
244 |
+
ahcfree_insert_search_engines_into_table($searchEngines);
|
245 |
+
}
|
246 |
+
|
247 |
+
if (ahcfree_getBrowsersCount() == 0) {
|
248 |
+
ahcfree_insert_browsers_into_table($browsers);
|
249 |
}
|
|
|
250 |
}
|
|
|
|
|
251 |
|
252 |
|
253 |
+
ahcfree_update_tables();
|
254 |
+
}
|
255 |
+
|
256 |
//--------------------------------------------
|
257 |
/**
|
258 |
* Called when plugin is deactivated
|
259 |
*
|
260 |
* @return void
|
261 |
*/
|
262 |
+
function ahcfree_unset_default_options() {
|
263 |
+
|
264 |
}
|
265 |
+
|
266 |
//--------------------------------------------
|
267 |
/**
|
268 |
* Creates plugin page link in the admin menu
|
272 |
*
|
273 |
* @return void
|
274 |
*/
|
275 |
+
function ahcfree_create_admin_menu_link() {
|
276 |
+
|
277 |
+
global $current_user;
|
278 |
+
$ahcUserRole = explode(',',get_option('ahcUserRoles'));
|
279 |
+
|
280 |
+
$roles_arr = array();
|
281 |
+
|
282 |
+
foreach($ahcUserRole as $v) {
|
283 |
+
$roles_arr[] = strtolower($v);
|
284 |
+
}
|
285 |
+
|
286 |
+
if (! in_array( strtolower($current_user->roles[0]), $roles_arr ) && !(current_user_can('manage_options'))) {
|
287 |
+
|
288 |
+
return;
|
289 |
+
}
|
290 |
+
|
291 |
+
add_menu_page('Visitor Traffic Real Time Statistics', 'Visitor Traffic', 'manage_categories', 'ahc_hits_counter_menu_free', 'ahcfree_create_plugin_overview_page', plugins_url('/images/vtrts.png', AHCFREE_PLUGIN_MAIN_FILE));
|
292 |
+
add_submenu_page('ahc_hits_counter_menu_free', 'Visitor Traffic Real Time Statistics Settings', 'Settings', 'manage_categories', 'ahc_hits_counter_settings', 'ahcfree_create_plugin_settings_page');
|
293 |
+
$ahcfree_custom_timezone = get_option( 'ahcfree_custom_timezone', false );
|
294 |
+
if( !$ahcfree_custom_timezone ){
|
295 |
+
add_action('admin_notices', 'ahcfree_admin_notice_to_set_timezone');
|
296 |
+
}
|
297 |
+
$page = isset($_GET['page']) ? ahcfree_sanitizing($_GET['page']) : '';
|
298 |
+
|
299 |
+
if( $page == 'ahc_hits_counter_settings' ){
|
300 |
+
remove_action('admin_notices', 'ahcfree_admin_notice_to_set_timezone');
|
301 |
+
}
|
302 |
+
}
|
303 |
+
|
304 |
+
//--------------------------------------------
|
305 |
+
/**
|
306 |
+
* Format numbers
|
307 |
+
*
|
308 |
+
* @return number
|
309 |
+
*/
|
310 |
+
function ahcfree_free_NumFormat($num) {
|
311 |
+
if ($num > 1000) {
|
312 |
+
return number_format($num, 0, ',', ',');
|
313 |
+
} else {
|
314 |
+
return $num;
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
//------
|
319 |
+
function ahcfree_countOnlineusers() {
|
320 |
+
global $wpdb;
|
321 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
322 |
+
|
323 |
+
$sql = "SELECT id FROM ahc_online_users WHERE `date` >= '". date("Y-m-d H:i:s", strtotime('-1 minute') ) ."' GROUP BY hit_ip_address";
|
324 |
+
$result = $wpdb->get_results($sql, OBJECT);
|
325 |
+
$online_users = "0";
|
326 |
+
if ($result !== false) {
|
327 |
+
$online_users = count($result);
|
328 |
+
//return $result[0]->onlineusers;
|
329 |
+
//echo json_encode($result[0]->onlineusers);
|
330 |
+
}
|
331 |
+
if( is_admin() ){
|
332 |
+
echo json_encode($online_users);
|
333 |
+
die;
|
334 |
+
}else{
|
335 |
+
return $online_users;
|
336 |
+
}
|
337 |
+
|
338 |
+
//return '0';
|
339 |
+
|
340 |
+
}
|
341 |
+
|
342 |
+
function ahcfree_init()
|
343 |
+
{
|
344 |
+
|
345 |
+
add_action('wp_ajax_ahcfree_track_visitor','ahcfree_track_visitor');
|
346 |
+
add_action('wp_ajax_nopriv_ahcfree_track_visitor','ahcfree_track_visitor');
|
347 |
+
}
|
348 |
+
add_action('admin_init','ahcfree_init');
|
349 |
+
|
350 |
+
function ahcfree_enqueue_scripts()
|
351 |
+
{
|
352 |
+
global $post, $wp_query;
|
353 |
+
$post_id = "HOMEPAGE";
|
354 |
+
$page_title = '';
|
355 |
+
$post_type = '';
|
356 |
+
if(is_singular() || is_page() )
|
357 |
+
{
|
358 |
+
$post_id = $post->ID;
|
359 |
+
$page_title = get_the_title($post->ID);
|
360 |
+
$post_type = get_post_type($post->ID);
|
361 |
+
}
|
362 |
+
if ( is_home() ) {
|
363 |
+
$post_id = "BLOGPAGE";
|
364 |
+
}
|
365 |
+
if( is_archive() ){
|
366 |
+
$post_id = get_the_archive_title();
|
367 |
+
}
|
368 |
+
|
369 |
+
|
370 |
+
wp_register_script('ahcfree_front_js', plugins_url('/js/front.js', AHCFREE_PLUGIN_MAIN_FILE),'jquery', '', false);
|
371 |
+
wp_enqueue_script('ahcfree_front_js');
|
372 |
+
|
373 |
+
wp_localize_script('ahcfree_front_js', 'ahcfree_ajax_front', array('ajax_url' => admin_url('admin-ajax.php'),
|
374 |
+
'page_id' => $post_id,
|
375 |
+
'page_title'=> $page_title,
|
376 |
+
'post_type'=> $post_type
|
377 |
+
));
|
378 |
}
|
379 |
+
add_action('wp_enqueue_scripts','ahcfree_enqueue_scripts', 1);
|
380 |
//--------------------------------------------
|
381 |
/**
|
382 |
* Creates the main overview page
|
383 |
*
|
384 |
* @return void
|
385 |
*/
|
386 |
+
function ahcfree_create_plugin_overview_page() {
|
387 |
+
require_once(AHCFREE_PLUGIN_ROOT_DIR . AHCFREE_DS . 'lang' . AHCFREE_DS . Globalsahcfree::$lang . '_lang.php');
|
388 |
+
include("overview.php");
|
389 |
+
}
|
390 |
+
|
391 |
+
//--------------------------------------------
|
392 |
+
/**
|
393 |
+
* Creates the plugin settings
|
394 |
+
*
|
395 |
+
* @return void
|
396 |
+
*/
|
397 |
+
function ahcfree_create_plugin_settings_page() {
|
398 |
+
|
399 |
+
require_once(AHCFREE_PLUGIN_ROOT_DIR . AHCFREE_DS . 'lang' . AHCFREE_DS . Globalsahcfree::$lang . '_lang.php');
|
400 |
+
include("ahc_settings.php");
|
401 |
+
}
|
402 |
+
|
403 |
+
//--------------------------------------------
|
404 |
+
/**
|
405 |
+
* Creates the plugin help page
|
406 |
+
*
|
407 |
+
* @return void
|
408 |
+
*/
|
409 |
+
function ahcfree_create_plugin_help_page() {
|
410 |
+
|
411 |
+
require_once(AHCFREE_PLUGIN_ROOT_DIR . AHCFREE_DS . 'lang' . AHCFREE_DS . Globalsahcfree::$lang . '_lang.php');
|
412 |
+
include("ahcfree_help.php");
|
413 |
+
}
|
414 |
+
|
415 |
+
//--------------------------------------------
|
416 |
+
/**
|
417 |
+
* Creates the plugin help page
|
418 |
+
*
|
419 |
+
* @return void
|
420 |
+
*/
|
421 |
+
function ahcfree_create_plugin_about_page() {
|
422 |
+
|
423 |
+
require_once(AHCFREE_PLUGIN_ROOT_DIR . AHCFREE_DS . 'lang' . AHCFREE_DS . Globalsahcfree::$lang . '_lang.php');
|
424 |
+
include("ahcfree_about.php");
|
425 |
}
|
426 |
+
|
427 |
//--------------------------------------------
|
428 |
/**
|
429 |
* Returns links array of available languages
|
433 |
*
|
434 |
* @return array
|
435 |
*/
|
436 |
+
function ahcfree_get_change_lang_links() {
|
437 |
+
$plugin_options = get_option('ahcfree_wp_hits_counter_options');
|
438 |
+
$links = array();
|
439 |
+
$i = 0;
|
440 |
+
foreach ($plugin_options['available_languages'] as $key => $value) {
|
441 |
+
if (Globalsahcfree::$lang != $key) {
|
442 |
+
$links[$i]['name'] = $value;
|
443 |
+
$links[$i]['href'] = add_query_arg('ahcfree_lang', $key);
|
444 |
+
$i++;
|
445 |
+
}
|
446 |
+
}
|
447 |
+
unset($plugin_options);
|
448 |
+
unset($i);
|
449 |
+
return $links;
|
450 |
}
|
451 |
+
|
452 |
//--------------------------------------------
|
453 |
/**
|
454 |
* Decides whether or not should track the current visitor
|
458 |
*
|
459 |
* @return boolean
|
460 |
*/
|
461 |
+
function ahcfree_should_track_visitor() {
|
462 |
+
global $current_user;
|
463 |
+
$allow = true;
|
464 |
+
if (is_user_logged_in()) {
|
465 |
+
$user = new WP_User($current_user->ID);
|
466 |
+
if (!empty($user->roles) && is_array($user->roles)) {
|
467 |
+
foreach ($user->roles as $role) {
|
468 |
+
$found = (isset(Globalsahcfree::$plugin_options['user_roles_to_not_track'][$role])) ? Globalsahcfree::$plugin_options['user_roles_to_not_track'][$role] : false;
|
469 |
+
if ($found) {
|
470 |
+
$allow = false;
|
471 |
+
break;
|
472 |
+
}
|
473 |
+
}
|
474 |
+
}
|
475 |
+
}
|
476 |
+
return $allow;
|
477 |
}
|
478 |
+
|
479 |
//--------------------------------------------
|
480 |
/**
|
481 |
* Returns true if the current user has administrator role
|
485 |
*
|
486 |
* @return boolean
|
487 |
*/
|
488 |
+
function ahcfree_has_administrator_role() {
|
489 |
+
global $user_ID;
|
490 |
+
$is_admin = false;
|
491 |
+
if (is_user_logged_in()) {
|
492 |
+
$user = new WP_User($user_ID);
|
493 |
+
if (!empty($user->roles) && is_array($user->roles)) {
|
494 |
+
foreach ($user->roles as $role) {
|
495 |
+
if ($role == 'administrator') {
|
496 |
+
$is_admin = true;
|
497 |
+
break;
|
498 |
+
}
|
499 |
+
}
|
500 |
+
}
|
501 |
+
}
|
502 |
+
return $is_admin;
|
503 |
}
|
504 |
+
|
505 |
//--------------------------------------------
|
506 |
/**
|
507 |
+
* Check if column exist or not
|
508 |
*
|
509 |
* @uses wpdb::query()
|
510 |
*
|
511 |
* @return boolean
|
512 |
*/
|
513 |
+
function ahcfree_check_table_column_exists($table_name, $column_name) {
|
514 |
+
global $wpdb;
|
515 |
+
$column = $wpdb->get_row($wpdb->prepare("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = %s ", DB_NAME, $table_name, $column_name));
|
516 |
+
|
517 |
+
if (!empty($column)) {
|
518 |
+
return true;
|
519 |
+
}
|
520 |
+
return false;
|
521 |
+
}
|
522 |
+
|
523 |
+
//--------------------------------------------
|
524 |
+
/**
|
525 |
+
* Check if Table exist or not
|
526 |
+
*
|
527 |
+
* @uses wpdb::query()
|
528 |
+
*
|
529 |
+
* @return boolean
|
530 |
+
*/
|
531 |
+
function ahcfree_check_table_exists($table_name) {
|
532 |
+
global $wpdb;
|
533 |
+
$table_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s", DB_NAME, $table_name));
|
534 |
+
|
535 |
+
if (!empty($table_data)) {
|
536 |
+
return true;
|
537 |
+
}
|
538 |
+
return false;
|
539 |
+
}
|
540 |
+
|
541 |
+
|
542 |
+
//--------------------------------------------
|
543 |
+
/**
|
544 |
+
* Creates database updates plugin tables
|
545 |
+
*
|
546 |
+
* @uses wpdb::query()
|
547 |
+
*
|
548 |
+
* @return boolean
|
549 |
+
*/
|
550 |
+
function ahcfree_update_tables() {
|
551 |
+
global $wpdb;
|
552 |
+
$sqlQueries = array();
|
553 |
+
|
554 |
+
$sqlQueries[] = " drop table IF EXISTS `ahc_settings` ";
|
555 |
+
$sqlQueries[] = "
|
556 |
+
CREATE TABLE IF NOT EXISTS `ahc_settings` (
|
557 |
+
`set_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
558 |
+
`set_hits_days` int(10) unsigned NOT NULL DEFAULT '30',
|
559 |
+
`set_ajax_check` int(10) unsigned NOT NULL DEFAULT '10',
|
560 |
+
`set_ips` text DEFAULT NULL,
|
561 |
+
`set_google_map` varchar(100) NOT NULL DEFAULT 'today_visitors',
|
562 |
+
|
563 |
+
PRIMARY KEY (`set_id`)
|
564 |
+
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
565 |
+
|
566 |
+
//$sqlQueries[] = "alter table `ahc_recent_visitors` add COLUMN `ahc_city` varchar(230) NULL";
|
567 |
+
//$sqlQueries[] = "alter table `ahc_recent_visitors` add COLUMN `ahc_region` varchar(230) NULL";
|
568 |
+
|
569 |
+
/* code for error handling : "duplicate column name" : Taslim -Prism */
|
570 |
+
if ( ahcfree_check_table_exists('ahc_recent_visitors') === true && ahcfree_check_table_column_exists('ahc_recent_visitors', 'ahc_city') === false ) {
|
571 |
+
$sqlQueries[] = "alter table `ahc_recent_visitors` add COLUMN `ahc_city` varchar(230) NULL";
|
572 |
+
}
|
573 |
+
|
574 |
+
if ( ahcfree_check_table_exists('ahc_recent_visitors') === true && ahcfree_check_table_column_exists('ahc_recent_visitors', 'ahc_region') === false ) {
|
575 |
+
$sqlQueries[] = "alter table `ahc_recent_visitors` add COLUMN `ahc_region` varchar(230) NULL";
|
576 |
+
}
|
577 |
+
|
578 |
+
foreach ($sqlQueries as $sql) {
|
579 |
+
if ($wpdb->query($sql) === false) {
|
580 |
+
return false;
|
581 |
+
}
|
582 |
+
}
|
583 |
+
|
584 |
+
|
585 |
+
return true;
|
586 |
+
}
|
587 |
+
|
588 |
+
function ahcfix_init(){
|
589 |
global $wpdb;
|
590 |
$sqlQueries = array();
|
591 |
+
if ( ahcfree_check_table_exists('ahc_visitors') === true && ahcfree_check_table_column_exists('ahc_visitors', 'vst_date') ) {
|
592 |
+
$sqlQueries[] = "ALTER TABLE `ahc_visitors` CHANGE `vst_date` `vst_date` DATETIME NOT NULL";
|
593 |
+
}
|
594 |
+
|
595 |
+
if ( ahcfree_check_table_exists('ahc_searching_visits') === true && ahcfree_check_table_column_exists('ahc_searching_visits', 'vtsh_date') ) {
|
596 |
+
$sqlQueries[] = "ALTER TABLE `ahc_searching_visits` CHANGE `vtsh_date` `vtsh_date` DATETIME NOT NULL";
|
597 |
+
}
|
598 |
+
|
599 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_online_users`
|
600 |
(
|
601 |
+
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
602 |
+
PRIMARY KEY(`id`),
|
603 |
`hit_ip_address` VARCHAR(50) NOT NULL,
|
|
|
|
|
604 |
`hit_page_id` VARCHAR(30) NOT NULL,
|
605 |
+
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
606 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
607 |
|
608 |
+
|
609 |
+
if( count($sqlQueries) ){
|
610 |
+
foreach ($sqlQueries as $sql) {
|
611 |
+
$wpdb->query($sql);
|
612 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
613 |
}
|
|
|
614 |
}
|
|
|
615 |
|
616 |
+
function ahcfree_add_settings() {
|
617 |
|
618 |
+
global $wpdb;
|
619 |
+
ahcfree_update_tables();
|
620 |
|
621 |
+
$sql1 = "truncate table `ahc_settings`";
|
622 |
+
$wpdb->query($sql1);
|
623 |
+
|
624 |
+
$sql = "insert into `ahc_settings` (set_id, set_hits_days, set_ajax_check, set_ips, set_google_map) values (1, 14, 15, null, 'today_visitors')";
|
625 |
+
|
626 |
+
|
627 |
+
if ($wpdb->query($sql) === false) {
|
628 |
+
return false;
|
629 |
+
}
|
630 |
+
return true;
|
631 |
+
}
|
632 |
+
|
633 |
+
//--------------------------------------------
|
634 |
+
/**
|
635 |
+
* Creates database plugin tables
|
636 |
+
*
|
637 |
+
* @uses wpdb::query()
|
638 |
+
*
|
639 |
+
* @return boolean
|
640 |
+
*/
|
641 |
+
function ahcfree_create_database_tables() {
|
642 |
+
global $wpdb;
|
643 |
+
$sqlQueries = array();
|
644 |
+
|
645 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_online_users`
|
646 |
+
(
|
647 |
+
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
648 |
+
PRIMARY KEY(`id`),
|
649 |
+
`hit_ip_address` VARCHAR(50) NOT NULL,
|
650 |
+
`hit_page_id` VARCHAR(30) NOT NULL,
|
651 |
+
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
652 |
+
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
653 |
+
|
654 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_hits`
|
655 |
(
|
656 |
`hit_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
657 |
PRIMARY KEY(`hit_id`),
|
669 |
`hit_date` DATE NOT NULL,
|
670 |
`hit_time` TIME NOT NULL
|
671 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
672 |
+
|
673 |
+
|
674 |
+
$sqlQueries[] = "
|
675 |
+
CREATE TABLE IF NOT EXISTS `ahc_settings` (
|
676 |
+
`set_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
677 |
+
`set_hits_days` int(10) unsigned NOT NULL DEFAULT '30',
|
678 |
+
`set_ajax_check` int(10) unsigned NOT NULL DEFAULT '10',
|
679 |
+
`set_ips` text DEFAULT NULL,
|
680 |
+
`set_google_map` varchar(100) NOT NULL DEFAULT 'today_visitors',
|
681 |
+
|
682 |
+
PRIMARY KEY (`set_id`)
|
683 |
+
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
684 |
+
|
685 |
+
|
686 |
+
|
687 |
+
|
688 |
+
|
689 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_browsers`
|
690 |
(
|
691 |
`bsr_id` INT(3) UNSIGNED NOT NULL,
|
692 |
PRIMARY KEY(`bsr_id`),
|
694 |
`bsr_icon` VARCHAR(50),
|
695 |
`bsr_visits` INT(11) NOT NULL DEFAULT 0
|
696 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
697 |
+
|
698 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_search_engines`
|
699 |
(
|
700 |
`srh_id` INT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
|
701 |
PRIMARY KEY(`srh_id`),
|
704 |
`srh_icon` VARCHAR(50),
|
705 |
`srh_identifier` VARCHAR(50)
|
706 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
707 |
+
|
708 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_search_engine_crawlers`
|
709 |
(
|
710 |
`bot_name` VARCHAR(50) NOT NULL,
|
711 |
`srh_id` INT(3) UNSIGNED NOT NULL
|
712 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
713 |
+
|
714 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_countries`
|
715 |
(
|
716 |
`ctr_id` INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
|
717 |
PRIMARY KEY(`ctr_id`),
|
722 |
`ctr_visitors` INT(11) NOT NULL DEFAULT 0,
|
723 |
`ctr_visits` INT(11) NOT NULL DEFAULT 0
|
724 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
725 |
+
|
726 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_visitors`
|
727 |
(
|
728 |
`vst_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
729 |
PRIMARY KEY (`vst_id`),
|
731 |
`vst_visitors` INT(11) UNSIGNED NULL DEFAULT 0,
|
732 |
`vst_visits` INT(11) UNSIGNED NULL DEFAULT 0
|
733 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
734 |
+
|
735 |
+
$sqlQueries[] = "ALTER TABLE `ahc_visitors` CHANGE `vst_date` `vst_date` DATETIME NOT NULL";
|
736 |
+
|
737 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_daily_visitors_stats`
|
738 |
+
(
|
739 |
+
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
740 |
+
PRIMARY KEY (`id`),
|
741 |
+
`vst_date` DATETIME NOT NULL,
|
742 |
+
`vst_visitors` INT(11) UNSIGNED NULL DEFAULT 0,
|
743 |
+
`vst_visits` INT(11) UNSIGNED NULL DEFAULT 0
|
744 |
+
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
745 |
+
|
746 |
+
|
747 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_searching_visits`
|
748 |
(
|
749 |
`vtsh_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
750 |
PRIMARY KEY (`vtsh_id`),
|
752 |
`vtsh_date` DATE NOT NULL,
|
753 |
`vtsh_visits` INT(11) UNSIGNED NOT NULL DEFAULT 0
|
754 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
755 |
+
|
756 |
+
$sqlQueries[] = "ALTER TABLE `ahc_searching_visits` CHANGE `vtsh_date` `vtsh_date` DATETIME NOT NULL";
|
757 |
+
|
758 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_refering_sites`
|
759 |
(
|
760 |
`rfr_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
761 |
PRIMARY KEY (`rfr_id`),
|
762 |
`rfr_site_name` VARCHAR(100) NOT NULL,
|
763 |
`rfr_visits` INT(11) UNSIGNED NULL DEFAULT 0
|
764 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
765 |
+
|
766 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_recent_visitors`
|
767 |
(
|
768 |
`vtr_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
769 |
PRIMARY KEY (`vtr_id`),
|
775 |
`vtr_date` DATE NOT NULL,
|
776 |
`vtr_time` TIME NOT NULL
|
777 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
778 |
+
|
779 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_keywords`
|
780 |
(
|
781 |
`kwd_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
782 |
PRIMARY KEY (`kwd_id`),
|
789 |
`kwd_date` DATE NOT NULL,
|
790 |
`kwd_time` TIME NOT NULL
|
791 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
792 |
+
|
793 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_title_traffic`
|
794 |
(
|
795 |
`til_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
796 |
PRIMARY KEY (`til_id`),
|
798 |
`til_page_title` VARCHAR(100),
|
799 |
`til_hits` INT(11) UNSIGNED NOT NULL
|
800 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
801 |
+
|
802 |
+
$sqlQueries[] = "CREATE TABLE IF NOT EXISTS `ahc_visits_time`
|
803 |
(
|
804 |
`vtm_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
805 |
PRIMARY KEY (`vtm_id`),
|
808 |
`vtm_visitors` INT(11) UNSIGNED NOT NULL DEFAULT 0,
|
809 |
`vtm_visits` INT(11) UNSIGNED NOT NULL DEFAULT 0
|
810 |
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
|
811 |
+
|
812 |
+
|
813 |
+
/* $sqlQueries[] = "alter table `ahc_recent_visitors` add COLUMN `ahc_city` varchar(230) NULL";
|
814 |
+
|
815 |
+
$sqlQueries[] = "alter table `ahc_recent_visitors` add COLUMN `ahc_region` varchar(230) NULL";
|
816 |
+
*/
|
817 |
+
|
818 |
+
|
819 |
+
foreach ($sqlQueries as $sql) {
|
820 |
+
if ($wpdb->query($sql) === false) {
|
821 |
+
return false;
|
822 |
+
}
|
823 |
+
}
|
824 |
+
return true;
|
825 |
}
|
826 |
+
|
827 |
//--------------------------------------------
|
828 |
/**
|
829 |
+
* Inserts countries into ahcfree_countroes table
|
830 |
*
|
831 |
* @uses wpdb::insert()
|
|
|
832 |
*
|
833 |
+
* @param array $internetCountryCodes. internet codes and names of countries
|
834 |
+
* @param array $contriesLatLng. LatLng of countries
|
835 |
* @return boolean
|
836 |
*/
|
837 |
+
function ahcfree_insert_countries_into_table($internetCountryCodes, $contriesLatLng) {
|
838 |
+
global $wpdb;
|
839 |
+
$c = 1;
|
840 |
+
$length = count($internetCountryCodes);
|
841 |
+
foreach ($internetCountryCodes as $internetCode => $countryName) {
|
842 |
+
$ctr_latitude = $ctr_longitude = NULL;
|
843 |
+
if (isset($contriesLatLng[$internetCode])) {
|
844 |
+
$ctr_latitude = $contriesLatLng[$internetCode][0];
|
845 |
+
$ctr_longitude = $contriesLatLng[$internetCode][1];
|
846 |
+
}
|
847 |
+
$result = $wpdb->insert('ahc_countries', array(
|
848 |
+
'ctr_name' => $countryName,
|
849 |
+
'ctr_internet_code' => $internetCode,
|
850 |
+
'ctr_latitude' => $ctr_latitude,
|
851 |
+
'ctr_longitude' => $ctr_longitude
|
852 |
+
), array(
|
853 |
+
'%s', '%s', '%s', '%s'
|
854 |
+
)
|
855 |
+
);
|
856 |
+
if ($result === false) {
|
857 |
+
return false;
|
858 |
+
}
|
859 |
+
}
|
860 |
+
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
}
|
862 |
+
|
863 |
//--------------------------------------------
|
864 |
/**
|
865 |
+
* Inserts search engines into ahc_search_engines table
|
866 |
*
|
867 |
* @uses wpdb::insert()
|
868 |
+
* @uses wpdb::$insert_id
|
869 |
*
|
870 |
+
* @param array $searchEngines.
|
871 |
* @return boolean
|
872 |
*/
|
873 |
+
function ahcfree_insert_search_engines_into_table($searchEngines) {
|
874 |
+
global $wpdb;
|
875 |
+
foreach ($searchEngines as $se) {
|
876 |
+
$result = $wpdb->insert('ahc_search_engines', array(
|
877 |
+
'srh_name' => $se['srh_name'],
|
878 |
+
'srh_query_parameter' => $se['srh_query_parameter'],
|
879 |
+
'srh_icon' => $se['srh_icon'],
|
880 |
+
'srh_identifier' => $se['srh_identifier']
|
881 |
+
), array(
|
882 |
+
'%s', '%s', '%s', '%s'
|
883 |
+
)
|
884 |
+
);
|
885 |
+
if ($result !== false) {
|
886 |
+
$srh_id = $wpdb->insert_id;
|
887 |
+
foreach ($se['crawlers'] as $crawler) {
|
888 |
+
$result2 = $wpdb->insert('ahc_search_engine_crawlers', array(
|
889 |
+
'bot_name' => $crawler,
|
890 |
+
'srh_id' => $srh_id
|
891 |
+
), array(
|
892 |
+
'%s', '%d'
|
893 |
+
)
|
894 |
+
);
|
895 |
+
if ($result2 === false) {
|
896 |
+
return false;
|
897 |
+
}
|
898 |
+
}
|
899 |
+
} else {
|
900 |
+
return false;
|
901 |
+
}
|
902 |
+
}
|
903 |
+
return true;
|
904 |
}
|
905 |
|
906 |
+
//--------------------------------------------
|
907 |
/**
|
908 |
+
* Inserts browsers into ahc_browsers table
|
909 |
*
|
910 |
* @uses wpdb::insert()
|
911 |
*
|
912 |
+
* @param array $browsers
|
|
|
913 |
* @return boolean
|
914 |
*/
|
915 |
+
function ahcfree_insert_browsers_into_table($browsers) {
|
916 |
+
global $wpdb;
|
917 |
+
foreach ($browsers as $browser) {
|
918 |
+
$result = $wpdb->insert('ahc_browsers', array(
|
919 |
+
'bsr_id' => $browser['bsr_id'],
|
920 |
+
'bsr_name' => $browser['bsr_name'],
|
921 |
+
'bsr_icon' => $browser['bsr_icon']
|
922 |
+
), array(
|
923 |
+
'%d', '%s', '%s'
|
924 |
+
)
|
925 |
+
);
|
926 |
+
if ($result === false) {
|
927 |
+
return false;
|
928 |
+
}
|
929 |
+
}
|
930 |
+
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
931 |
}
|
932 |
|
933 |
//--------------------------------------------
|
939 |
* @param array $dayHours
|
940 |
* @return boolean
|
941 |
*/
|
942 |
+
function ahcfree_insert_visit_times_into_table($dayHours) {
|
943 |
+
global $wpdb;
|
944 |
+
foreach ($dayHours as $t) {
|
945 |
+
$result = $wpdb->insert('ahc_visits_time', array(
|
946 |
+
'vtm_time_from' => $t['vtm_time_from'],
|
947 |
+
'vtm_time_to' => $t['vtm_time_to'],
|
948 |
+
'vtm_visitors' => 0
|
949 |
+
), array(
|
950 |
+
'%s', '%s', '%d'
|
951 |
+
)
|
952 |
+
);
|
953 |
+
if ($result === false) {
|
954 |
+
return false;
|
955 |
+
}
|
956 |
+
}
|
957 |
+
return true;
|
|
|
958 |
}
|
959 |
+
|
960 |
//--------------------------------------------
|
961 |
/**
|
962 |
* Returns the first and last days of the week of the date you pass
|
965 |
* @param string $format Optional
|
966 |
* @return array
|
967 |
*/
|
968 |
+
function ahcfree_get_week_limits($date, $format = 'Y-m-d') {
|
969 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
970 |
+
$beginingDay = new DateTime($date);
|
971 |
+
$custom_timezone = new DateTimeZone(ahcfree_get_timezone_string());
|
972 |
+
$endingDay = new DateTime($date);
|
973 |
+
$date = new DateTime($date);
|
974 |
+
switch ($date->format('w')) {
|
975 |
+
case 0: // sun
|
976 |
+
//$beginingDay->modify('-1 day');
|
977 |
+
$endingDay->modify('+6 day');
|
978 |
+
break;
|
979 |
+
|
980 |
+
case 1: // mon
|
981 |
+
$beginingDay->modify('-1 day');
|
982 |
+
$endingDay->modify('+5 day');
|
983 |
+
break;
|
984 |
+
|
985 |
+
case 2: // Tue
|
986 |
+
$beginingDay->modify('-2 day');
|
987 |
+
$endingDay->modify('+4 day');
|
988 |
+
break;
|
989 |
+
|
990 |
+
case 3: // Wed
|
991 |
+
$beginingDay->modify('-3 day');
|
992 |
+
$endingDay->modify('+3 day');
|
993 |
+
break;
|
994 |
+
|
995 |
+
case 4: // Thu
|
996 |
+
$beginingDay->modify('-4 day');
|
997 |
+
$endingDay->modify('+2 day');
|
998 |
+
break;
|
999 |
+
|
1000 |
+
case 6: // Fri
|
1001 |
+
$beginingDay->modify('-5 day');
|
1002 |
+
$endingDay->modify('+1 day');
|
1003 |
+
break;
|
1004 |
+
}
|
1005 |
+
$day = date('w');
|
1006 |
+
|
1007 |
+
$beginingDay->modify('-'.$day.' days');
|
1008 |
+
$endingDay->modify('+'.(6-$day).' days');
|
1009 |
+
return array(0 => $beginingDay->format($format), 1 => $endingDay->format($format));
|
1010 |
}
|
1011 |
+
|
1012 |
//--------------------------------------------
|
1013 |
/**
|
1014 |
* Return summary statistics of visitors and visits
|
1015 |
*
|
1016 |
* @return array
|
1017 |
*/
|
1018 |
+
function ahcfree_get_summary_statistics() {
|
1019 |
+
$arr = array();
|
1020 |
+
$arr['today'] = ahcfree_get_visitors_visits_in_period('today');
|
1021 |
+
$arr['yesterday'] = ahcfree_get_visitors_visits_in_period('yesterday');
|
1022 |
+
$arr['week'] = ahcfree_get_visitors_visits_in_period('week');
|
1023 |
+
$arr['month'] = ahcfree_get_visitors_visits_in_period('month');
|
1024 |
+
$arr['year'] = ahcfree_get_visitors_visits_in_period('year');
|
1025 |
+
$arr['total'] = ahcfree_get_visitors_visits_in_period();
|
1026 |
+
return $arr;
|
1027 |
}
|
1028 |
+
|
1029 |
//--------------------------------------------
|
1030 |
/**
|
1031 |
* Return counts visitors and visits in certain day (today|yesterday), certain period(last week, last month, last year) or total
|
1032 |
*
|
1033 |
* @uses wpdb::prepare()
|
1034 |
+
* @uses wpdb::get_results()
|
1035 |
+
*
|
1036 |
+
* @param string $period Optional
|
1037 |
+
* @return mixed
|
1038 |
+
*/
|
1039 |
+
function ahcfree_get_visitors_visits_in_period($period = 'total') {
|
1040 |
+
global $wpdb;
|
1041 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1042 |
+
$custom_timezone = new DateTimeZone(ahcfree_get_timezone_string());
|
1043 |
+
$date = new DateTime();
|
1044 |
+
$date->setTimezone($custom_timezone);
|
1045 |
+
$sql = "SELECT SUM(vst_visitors) AS vst_visitors, SUM(vst_visits) AS vst_visits
|
1046 |
+
FROM `ahc_visitors`
|
1047 |
+
WHERE 1 = 1";
|
1048 |
+
$results = false;
|
1049 |
+
switch ($period) {
|
1050 |
+
case 'today':
|
1051 |
+
$sql .= " AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) = '". date("Y-m-d") ."'";
|
1052 |
+
//$sql .= " AND DATE(vst_date) = DATE(NOW())";
|
1053 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
1054 |
+
break;
|
1055 |
+
|
1056 |
+
case 'yesterday':
|
1057 |
+
$date->modify('-1 day');
|
1058 |
+
$sql .= " AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) = %s";
|
1059 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $date->format('Y-m-d')), OBJECT);
|
1060 |
+
break;
|
1061 |
+
|
1062 |
+
case 'week':
|
1063 |
+
$limits = ahcfree_get_week_limits($date->format('Y-m-d'));
|
1064 |
+
$sql .= " AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= %s AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) <= %s";
|
1065 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $limits[0], $limits[1]), OBJECT);
|
1066 |
+
break;
|
1067 |
+
|
1068 |
+
case 'month':
|
1069 |
+
$sql .= " AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= %s AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) <= %s";
|
1070 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $date->format('Y-m-01'), $date->format('Y-m-d')), OBJECT);
|
1071 |
+
break;
|
1072 |
+
|
1073 |
+
case 'year':
|
1074 |
+
$sql .= " AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= %s AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) <= %s";
|
1075 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $date->format('Y-01-01'), $date->format('Y-12-31')), OBJECT);
|
1076 |
+
break;
|
1077 |
+
|
1078 |
+
default:
|
1079 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
1080 |
+
}
|
1081 |
+
//echo $wpdb->last_query.'<br />';
|
1082 |
+
if ($results !== false) {
|
1083 |
+
return array(
|
1084 |
+
'visitors' => (empty($results[0]->vst_visitors) ? 0 : $results[0]->vst_visitors),
|
1085 |
+
'visits' => (empty($results[0]->vst_visits) ? 0 : $results[0]->vst_visits)
|
1086 |
+
);
|
1087 |
+
} else {
|
1088 |
+
return false;
|
1089 |
+
}
|
1090 |
}
|
1091 |
+
|
1092 |
//--------------------------------------------
|
1093 |
/**
|
1094 |
* Return visits in a period from today
|
1098 |
*
|
1099 |
* @return array
|
1100 |
*/
|
1101 |
+
function ahcfree_get_visitors_visits_by_date() {
|
1102 |
global $wpdb;
|
1103 |
$lastDays = AHC_VISITORS_VISITS_LIMIT - 1;
|
1104 |
$response = array();
|
1105 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1106 |
+
$custom_timezone = new DateTimeZone(ahcfree_get_timezone_string());
|
1107 |
$beginning = new DateTime();
|
1108 |
+
$beginning->setTimezone($custom_timezone);
|
1109 |
+
$beginning->modify('-' . $lastDays . ' day');
|
1110 |
+
|
1111 |
+
$sql = "SELECT DATE(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) as vst_date, vst_visitors, vst_visits
|
1112 |
FROM ahc_visitors
|
1113 |
+
WHERE DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= DATE(CONVERT_TZ(%s, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'))";
|
1114 |
+
|
|
|
1115 |
$results = $wpdb->get_results($wpdb->prepare($sql, $beginning->format('Y-m-d')), OBJECT);
|
1116 |
+
if ($results !== false) {
|
1117 |
$response['success'] = true;
|
1118 |
$response['date'] = array();
|
1119 |
+
for ($i = count($results); $i < $lastDays; $i++) {
|
1120 |
$beginning->modify('+1 day');
|
1121 |
$response['data']['dates'][] = $beginning->format('d/m');
|
1122 |
$response['data']['visitors'][] = 0;
|
1123 |
$response['data']['visits'][] = 0;
|
1124 |
}
|
1125 |
+
|
1126 |
+
foreach ($results as $r) {
|
1127 |
$hitDate = new DateTime($r->vst_date);
|
1128 |
+
//$hitDate->setTimezone($custom_timezone);
|
1129 |
$response['data']['dates'][] = $hitDate->format('d/m');
|
1130 |
$response['data']['visitors'][] = $r->vst_visitors;
|
1131 |
$response['data']['visits'][] = $r->vst_visits;
|
1132 |
}
|
1133 |
+
} else {
|
1134 |
$response['success'] = false;
|
1135 |
}
|
1136 |
return $response;
|
1137 |
}
|
1138 |
+
|
1139 |
+
function ahcfree_get_visitors_by_date() {
|
1140 |
+
global $wpdb;
|
1141 |
+
$lastDays = AHC_VISITORS_VISITS_LIMIT;
|
1142 |
+
$response = array();
|
1143 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1144 |
+
$custom_timezone = new DateTimeZone(ahcfree_get_timezone_string());
|
1145 |
+
$beginning = new DateTime();
|
1146 |
+
$beginning->setTimezone($custom_timezone);
|
1147 |
+
$beginning->modify('-' . $lastDays . ' day');
|
1148 |
+
|
1149 |
+
|
1150 |
+
$sql = "SELECT DATE(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) as vst_date, vst_visitors
|
1151 |
+
FROM ahc_visitors
|
1152 |
+
WHERE DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= DATE(CONVERT_TZ(%s, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'))";
|
1153 |
+
|
1154 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $beginning->format('Y-m-d')), OBJECT);
|
1155 |
+
|
1156 |
+
if ($results !== false) {
|
1157 |
+
for ($i = count($results); $i < $lastDays; $i++) {
|
1158 |
+
$beginning->modify('+1 day');
|
1159 |
+
$xx .= "['" . $beginning->format('Y-m-d') . "', 0], ";
|
1160 |
+
}
|
1161 |
+
foreach ($results as $r) {
|
1162 |
+
|
1163 |
+
$hitDate = new DateTime($r->vst_date);
|
1164 |
+
//$hitDate->setTimezone($custom_timezone);
|
1165 |
+
$xx .= "['" . $hitDate->format('Y-m-d') . "', " . $r->vst_visitors . "], ";
|
1166 |
+
}
|
1167 |
+
}
|
1168 |
+
return '[' . $xx . ']';
|
1169 |
+
}
|
1170 |
+
|
1171 |
+
function ahcfree_get_visits_by_date() {
|
1172 |
+
global $wpdb;
|
1173 |
+
$lastDays = AHC_VISITORS_VISITS_LIMIT;
|
1174 |
+
$response = array();
|
1175 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1176 |
+
$custom_timezone = new DateTimeZone(ahcfree_get_timezone_string());
|
1177 |
+
$beginning = new DateTime();
|
1178 |
+
$beginning->setTimezone($custom_timezone);
|
1179 |
+
$beginning->modify('-' . $lastDays . ' day');
|
1180 |
+
|
1181 |
+
$sql = "SELECT DATE(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) as vst_date, vst_visits
|
1182 |
+
FROM ahc_visitors
|
1183 |
+
WHERE DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= DATE(CONVERT_TZ(%s, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'))";
|
1184 |
+
|
1185 |
+
|
1186 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $beginning->format('Y-m-d')), OBJECT);
|
1187 |
+
if ($results !== false) {
|
1188 |
+
for ($i = count($results); $i < $lastDays; $i++) {
|
1189 |
+
$beginning->modify('+1 day');
|
1190 |
+
$x .= "['" . $beginning->format('Y-m-d') . "', 0], ";
|
1191 |
+
}
|
1192 |
+
foreach ($results as $r) {
|
1193 |
+
$hitDate = new DateTime($r->vst_date);
|
1194 |
+
//$hitDate->setTimezone($custom_timezone);
|
1195 |
+
$x .= "['" . $hitDate->format('Y-m-d') . "', " . $r->vst_visits . "], ";
|
1196 |
+
}
|
1197 |
+
}
|
1198 |
+
return '[' . $x . ']';
|
1199 |
}
|
1200 |
+
|
1201 |
+
|
1202 |
+
|
1203 |
//--------------------------------------------
|
1204 |
/**
|
1205 |
* Returns the total visits by search engines
|
1208 |
*
|
1209 |
* @return mixed
|
1210 |
*/
|
1211 |
+
function ahcfree_get_total_visits_by_search_engines() {
|
1212 |
+
global $wpdb;
|
1213 |
+
$result = $wpdb->get_results("SELECT SUM(vtsh_visits) AS total FROM ahc_searching_visits", OBJECT);
|
1214 |
+
if ($result !== false) {
|
1215 |
+
return $result[0]->total;
|
1216 |
+
}
|
1217 |
+
return false;
|
1218 |
}
|
1219 |
+
|
1220 |
//--------------------------------------------
|
1221 |
/**
|
1222 |
* Return counts visits happened by search engine result in certain day (today|yesterday), certain period(last week, last month, last year) or total
|
1227 |
* @param string $period Optional
|
1228 |
* @return mixed
|
1229 |
*/
|
1230 |
+
function ahcfree_get_hits_search_engines_referers($period = 'total') {
|
1231 |
+
global $wpdb;
|
1232 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1233 |
+
$custom_timezone = new DateTimeZone(ahcfree_get_timezone_string());
|
1234 |
+
$date = new DateTime();
|
1235 |
+
$date->setTimezone($custom_timezone);
|
1236 |
+
$sql = "SELECT srh_id, vtsh_visits
|
1237 |
FROM `ahc_searching_visits`";
|
1238 |
+
$results = false;
|
1239 |
+
switch ($period) {
|
1240 |
+
case 'today':
|
1241 |
+
$sql .= " WHERE DATE(CONVERT_TZ(vtsh_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) = DATE(CONVERT_TZ('". date('Y-m-d H:i:s') ."', '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'))";
|
1242 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
1243 |
+
break;
|
1244 |
+
|
1245 |
+
case 'yesterday':
|
1246 |
+
$date->modify('-1 day');
|
1247 |
+
$sql .= " WHERE DATE(CONVERT_TZ(vtsh_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) = DATE(CONVERT_TZ(%s, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'))";
|
1248 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $date->format('Y-m-d')), OBJECT);
|
1249 |
+
break;
|
1250 |
+
|
1251 |
+
case 'week':
|
1252 |
+
$limits = ahcfree_get_week_limits($date->format('Y-m-d'));
|
1253 |
+
$sql .= " WHERE DATE(CONVERT_TZ(vtsh_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= DATE(CONVERT_TZ(%s, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) AND DATE(CONVERT_TZ(vtsh_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) <= DATE(CONVERT_TZ(%s, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'))";
|
1254 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $limits[0], $limits[1]), OBJECT);
|
1255 |
+
break;
|
1256 |
+
|
1257 |
+
case 'month':
|
1258 |
+
$sql .= " WHERE DATE(CONVERT_TZ(vtsh_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= DATE(CONVERT_TZ('" . $date->format('Y-m-01') . "', '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) AND DATE(CONVERT_TZ(vtsh_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) <= DATE(CONVERT_TZ('" . $date->format('Y-m-t') . "', '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'))";
|
1259 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $limits[0], $limits[1]), OBJECT);
|
1260 |
+
break;
|
1261 |
+
|
1262 |
+
case 'year':
|
1263 |
+
$sql .= " WHERE DATE(CONVERT_TZ(vtsh_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= DATE(CONVERT_TZ(%s, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) AND DATE(CONVERT_TZ(vtsh_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) <= DATE(CONVERT_TZ(%s, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'))";
|
1264 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $date->format('Y-01-01'), $date->format('Y-12-31')), OBJECT);
|
1265 |
+
break;
|
1266 |
+
|
1267 |
+
default:
|
1268 |
+
}
|
1269 |
+
|
1270 |
+
$hitsReferers = array();
|
1271 |
+
if ($results !== false) {
|
1272 |
+
foreach ($results as $r) {
|
1273 |
+
$hitsReferers[$r->srh_id] = $r->vtsh_visits;
|
1274 |
+
}
|
1275 |
+
return $hitsReferers;
|
1276 |
+
}
|
1277 |
+
return false;
|
|
|
1278 |
}
|
1279 |
+
|
1280 |
//--------------------------------------------
|
1281 |
/**
|
1282 |
* Retrieves all search engines
|
1285 |
*
|
1286 |
* @return mixed
|
1287 |
*/
|
1288 |
+
function ahcfree_get_all_search_engines() {
|
1289 |
+
global $wpdb;
|
1290 |
+
$sql = "SELECT `srh_id`, `srh_name`, `srh_icon` FROM `ahc_search_engines`";
|
1291 |
+
$searchEngines = array();
|
1292 |
+
$c = 0;
|
1293 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
1294 |
+
if ($results !== false) {
|
1295 |
+
foreach ($results as $re) {
|
1296 |
+
$searchEngines[$c]['srh_id'] = $re->srh_id;
|
1297 |
+
$searchEngines[$c]['srh_name'] = $re->srh_name;
|
1298 |
+
$searchEngines[$c]['srh_icon'] = $re->srh_icon;
|
1299 |
+
$c++;
|
1300 |
+
}
|
1301 |
+
return $searchEngines;
|
1302 |
+
}
|
1303 |
+
return false;
|
1304 |
}
|
1305 |
+
|
1306 |
//--------------------------------------------
|
1307 |
/**
|
1308 |
* Retrieves count of visits order by browsers
|
1311 |
*
|
1312 |
* @return array
|
1313 |
*/
|
1314 |
+
function ahcfree_get_browsers_hits_counts() {
|
1315 |
+
global $wpdb;
|
1316 |
+
$sql = "SELECT `bsr_id`, `bsr_name`, `bsr_visits`
|
1317 |
FROM `ahc_browsers`
|
1318 |
WHERE `bsr_visits` > 0";
|
1319 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
1320 |
+
$response = array();
|
1321 |
+
if ($results !== false) {
|
1322 |
+
$response['success'] = true;
|
1323 |
+
$response['data'] = array();
|
1324 |
+
$c = 0;
|
1325 |
+
foreach ($results as $bsr) {
|
1326 |
+
$response['data'][$c]['bsr_id'] = $bsr->bsr_id;
|
1327 |
+
$response['data'][$c]['bsr_name'] = $bsr->bsr_name;
|
1328 |
+
$response['data'][$c]['hits'] = $bsr->bsr_visits;
|
1329 |
+
$c++;
|
1330 |
+
}
|
1331 |
+
} else {
|
1332 |
+
$response['success'] = false;
|
1333 |
+
}
|
1334 |
+
return $response;
|
1335 |
+
}
|
1336 |
+
|
1337 |
+
//--------------------------------------------
|
1338 |
+
/**
|
1339 |
+
* Return visitors visits that came from search engine in a period from today
|
1340 |
+
*
|
1341 |
+
* @uses wpdb::prepare()
|
1342 |
+
* @uses wpdb::get_results()
|
1343 |
+
*
|
1344 |
+
* @return array
|
1345 |
+
*/
|
1346 |
+
|
1347 |
+
|
1348 |
+
function ahcfree_get_serch_visits_by_date() {
|
1349 |
+
global $wpdb;
|
1350 |
+
|
1351 |
+
$sql = "SELECT srh_name, sum(vtsh_visits) as vtsh_visits, ase.srh_id FROM ahc_searching_visits asv, ahc_search_engines ase where asv.srh_id = ase.srh_id group by ase.srh_id";
|
1352 |
+
|
1353 |
+
|
1354 |
+
|
1355 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
1356 |
+
$response = array();
|
1357 |
+
if ($results !== false) {
|
1358 |
+
$response['success'] = true;
|
1359 |
+
$response['data'] = array();
|
1360 |
+
$c = 0;
|
1361 |
+
foreach ($results as $bsr) {
|
1362 |
+
$response['data'][$c]['bsr_id'] = $bsr->srh_id;
|
1363 |
+
$response['data'][$c]['bsr_name'] = $bsr->srh_name;
|
1364 |
+
$response['data'][$c]['hits'] = $bsr->vtsh_visits;
|
1365 |
+
$c++;
|
1366 |
+
}
|
1367 |
+
} else {
|
1368 |
+
$response['success'] = false;
|
1369 |
+
}
|
1370 |
+
|
1371 |
+
return $response;
|
1372 |
}
|
1373 |
+
|
1374 |
//--------------------------------------------
|
1375 |
/**
|
1376 |
* Retrieves top referring sites
|
1380 |
*
|
1381 |
* @return mixed
|
1382 |
*/
|
1383 |
+
function ahcfree_get_top_refering_sites() {
|
1384 |
+
global $wpdb;
|
1385 |
+
$sql = "SELECT rfr_site_name, rfr_visits
|
1386 |
FROM `ahc_refering_sites`
|
1387 |
ORDER BY rfr_visits DESC
|
1388 |
LIMIT %d OFFSET 0";
|
1389 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, AHCFREE_TOP_REFERING_SITES_LIMIT), OBJECT);
|
1390 |
+
if ($results !== false) {
|
1391 |
+
$arr = array();
|
1392 |
+
$c = 0;
|
1393 |
+
foreach ($results as $referer) {
|
1394 |
+
$arr[$c]['site_name'] = $referer->rfr_site_name;
|
1395 |
+
$arr[$c]['total_hits'] = $referer->rfr_visits;
|
1396 |
+
$c++;
|
1397 |
+
}
|
1398 |
+
return $arr;
|
1399 |
+
} else {
|
1400 |
+
return false;
|
1401 |
+
}
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
//--------------------------------------------
|
1405 |
+
/**
|
1406 |
+
* Retrieves countries related to visits
|
1407 |
+
*
|
1408 |
+
* @uses wpdb::prepare()
|
1409 |
+
* @uses wpdb::get_results()
|
1410 |
+
*
|
1411 |
+
* @return mixed
|
1412 |
+
*/
|
1413 |
+
function ahcfree_get_top_countries( $limit = 0 ) {
|
1414 |
+
global $wpdb;
|
1415 |
+
if( $limit == 0 ){
|
1416 |
+
$limit = AHCFREE_TOP_COUNTRIES_LIMIT;
|
1417 |
+
}
|
1418 |
+
|
1419 |
+
$sql = "SELECT ctr_name, ctr_internet_code, ctr_visitors, ctr_visits
|
1420 |
+
FROM `ahc_countries` WHERE ctr_visits > 0
|
1421 |
+
ORDER BY ctr_visitors DESC
|
1422 |
+
LIMIT %d OFFSET 0";
|
1423 |
+
|
1424 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, $limit), OBJECT);
|
1425 |
+
$response = array();
|
1426 |
+
if ($results !== false) {
|
1427 |
+
$response['success'] = true;
|
1428 |
+
$response['data'] = array();
|
1429 |
+
$c = 0;
|
1430 |
+
foreach ($results as $ctr) {
|
1431 |
+
$response['data'][$c]['ctr_name'] = $ctr->ctr_name;
|
1432 |
+
$response['data'][$c]['ctr_internet_code'] = $ctr->ctr_internet_code;
|
1433 |
+
$response['data'][$c]['visitors'] = $ctr->ctr_visitors;
|
1434 |
+
$response['data'][$c]['visits'] = $ctr->ctr_visits;
|
1435 |
+
$c++;
|
1436 |
+
}
|
1437 |
+
} else {
|
1438 |
+
$response['success'] = false;
|
1439 |
+
}
|
1440 |
+
|
1441 |
+
return $response;
|
1442 |
}
|
1443 |
+
|
1444 |
+
//--------------------------------------------
|
1445 |
+
/**
|
1446 |
+
* Retrieves countries related to visits
|
1447 |
+
*
|
1448 |
+
* @uses wpdb::prepare()
|
1449 |
+
* @uses wpdb::get_results()
|
1450 |
+
*
|
1451 |
+
* @return mixed
|
1452 |
+
*/
|
1453 |
+
function ahcfree_get_vsitors_by_country() {
|
1454 |
+
global $wpdb;
|
1455 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1456 |
+
$sql = "select tot.ctr_name, tot.ctr_internet_code, tot.total from (SELECT c.ctr_name, c.ctr_internet_code, count(1) as total
|
1457 |
+
FROM ahc_recent_visitors v, ahc_countries c where v.ctr_id = c.ctr_id and DATE(CONVERT_TZ(vtr_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) = DATE(CONVERT_TZ(NOW(),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) group by ctr_name) as tot order by tot.total desc";
|
1458 |
+
|
1459 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, AHCFREE_TOP_COUNTRIES_LIMIT), OBJECT);
|
1460 |
+
if ($results !== false) {
|
1461 |
+
$arr = array();
|
1462 |
+
$c = 0;
|
1463 |
+
foreach ($results as $ctr) {
|
1464 |
+
if ($ctr->total > 1) {
|
1465 |
+
$arr[$c]['ctr_name'] = $ctr->ctr_name;
|
1466 |
+
$arr[$c]['ctr_internet_code'] = $ctr->ctr_internet_code;
|
1467 |
+
$arr[$c]['total'] = $ctr->total;
|
1468 |
+
} else {
|
1469 |
+
$arr[9999]['ctr_name'] = 'others';
|
1470 |
+
$arr[9999]['ctr_internet_code'] = 'XX';
|
1471 |
+
$arr[9999]['total'] += 1;
|
1472 |
+
}
|
1473 |
+
$c++;
|
1474 |
+
}
|
1475 |
+
return $arr;
|
1476 |
+
} else {
|
1477 |
+
return false;
|
1478 |
+
}
|
1479 |
+
}
|
1480 |
+
|
1481 |
//--------------------------------------------
|
1482 |
/**
|
1483 |
* Retrieves recent visitors
|
1487 |
*
|
1488 |
* @return mixed
|
1489 |
*/
|
1490 |
+
function ahcfree_get_recent_visitors() {
|
1491 |
+
global $wpdb, $_SERVER;
|
1492 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1493 |
+
$sql_query = "SELECT v.vtr_id, v.vtr_ip_address, v.vtr_referer, DATE_FORMAT(CONVERT_TZ(CONCAT_WS(' ',v.vtr_date,v.vtr_time),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "'), '%Y-%m-%d') as vtr_date, DATE_FORMAT(CONVERT_TZ(CONCAT_WS(' ',v.vtr_date,v.vtr_time),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "'), '%H:%i:%s') as vtr_time, v.ahc_city, v.ahc_region,
|
1494 |
+
c.ctr_name, c.ctr_internet_code, b.bsr_name, b.bsr_icon
|
1495 |
FROM `ahc_recent_visitors` AS v
|
1496 |
+
LEFT JOIN `ahc_countries` AS c ON v.ctr_id = c.ctr_id
|
1497 |
+
LEFT JOIN `ahc_browsers` AS b ON v.bsr_id = b.bsr_id
|
1498 |
WHERE v.vtr_ip_address NOT LIKE 'UNKNOWN%%'
|
1499 |
+
ORDER BY v.vtr_id DESC
|
1500 |
+
LIMIT " . AHC_RECENT_VISITORS_LIMIT . " OFFSET 0";
|
1501 |
+
|
1502 |
+
/* $sql_query = "SELECT v.vtr_id, v.vtr_ip_address, v.vtr_referer, DATE_FORMAT(CONVERT_TZ(v.vtr_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "'), '%Y-%m-%d') as vtr_date, DATE_FORMAT(CONVERT_TZ(v.vtr_time,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "'), '%H:%i:%s') as vtr_time, v.ahc_city, v.ahc_region,
|
1503 |
+
c.ctr_name, c.ctr_internet_code, b.bsr_name, b.bsr_icon
|
1504 |
+
FROM `ahc_recent_visitors` AS v
|
1505 |
+
LEFT JOIN `ahc_countries` AS c ON v.ctr_id = c.ctr_id
|
1506 |
+
LEFT JOIN `ahc_browsers` AS b ON v.bsr_id = b.bsr_id
|
1507 |
+
WHERE v.vtr_ip_address NOT LIKE 'UNKNOWN%%'
|
1508 |
+
ORDER BY v.vtr_id DESC
|
1509 |
+
LIMIT " . AHC_RECENT_VISITORS_LIMIT . " OFFSET 0"; */
|
1510 |
+
|
1511 |
+
$results = $wpdb->get_results($sql_query);
|
1512 |
+
if ($results !== false) {
|
1513 |
+
$arr = array();
|
1514 |
+
$c = 0;
|
1515 |
+
if (is_array($results)) {
|
1516 |
+
foreach ($results as $hit) {
|
1517 |
+
if (strlen($hit->vtr_ip_address) < 17) {
|
1518 |
+
$arr[$c]['hit_id'] = $hit->vtr_id;
|
1519 |
+
$arr[$c]['hit_ip_address'] = $hit->vtr_ip_address;
|
1520 |
+
$arr[$c]['hit_referer'] = (parse_url($hit->vtr_referer, PHP_URL_HOST) == $_SERVER['SERVER_NAME']) ? '' : rawurldecode($hit->vtr_referer);
|
1521 |
+
$arr[$c]['hit_date'] = $hit->vtr_date;
|
1522 |
+
$arr[$c]['hit_time'] = $hit->vtr_time;
|
1523 |
+
$arr[$c]['ctr_name'] = $hit->ctr_name;
|
1524 |
+
$arr[$c]['ctr_internet_code'] = $hit->ctr_internet_code;
|
1525 |
+
$arr[$c]['bsr_name'] = $hit->bsr_name;
|
1526 |
+
$arr[$c]['bsr_icon'] = $hit->bsr_icon;
|
1527 |
+
$arr[$c]['ahc_city'] = $hit->ahc_city;
|
1528 |
+
$arr[$c]['ahc_region'] = $hit->ahc_region;
|
1529 |
+
|
1530 |
+
$c++;
|
1531 |
+
}
|
1532 |
+
}
|
1533 |
+
}
|
1534 |
+
return $arr;
|
1535 |
+
} else {
|
1536 |
+
return false;
|
1537 |
+
}
|
1538 |
}
|
1539 |
+
|
1540 |
//--------------------------------------------
|
1541 |
/**
|
1542 |
* Retrieves latest of key words used in search
|
1546 |
*
|
1547 |
* @return mixed
|
1548 |
*/
|
1549 |
+
function ahcfree_get_latest_search_key_words_used() {
|
1550 |
+
global $wpdb;
|
1551 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1552 |
+
$sql = "SELECT k.kwd_ip_address, k.kwd_referer, k.kwd_keywords, CONVERT_TZ(CONCAT_WS(' ',k.kwd_date,k.kwd_time),'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') as kwd_date, CONVERT_TZ(k.kwd_time,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') as kwd_time, k.ctr_id,
|
1553 |
+
c.ctr_name, c.ctr_internet_code, b.bsr_name, b.bsr_icon, s.srh_name, s.srh_icon
|
1554 |
FROM `ahc_keywords` AS k
|
1555 |
+
LEFT JOIN `ahc_countries` AS c ON k.ctr_id = c.ctr_id
|
1556 |
JOIN `ahc_browsers` AS b ON k.bsr_id = b.bsr_id
|
1557 |
JOIN `ahc_search_engines` AS s on k.srh_id = s.srh_id
|
1558 |
+
WHERE k.kwd_ip_address != 'UNKNOWN'
|
1559 |
ORDER BY k.kwd_date DESC, k.kwd_time DESC
|
1560 |
LIMIT %d OFFSET 0";
|
1561 |
+
|
1562 |
+
$results = $wpdb->get_results($wpdb->prepare($sql, AHCFREE_RECENT_KEYWORDS_LIMIT), OBJECT);
|
1563 |
+
if ($results !== false) {
|
1564 |
+
$arr = array();
|
1565 |
+
$c = 0;
|
1566 |
+
foreach ($results as $re) {
|
1567 |
+
|
1568 |
+
$arr[$c]['hit_referer'] = rawurldecode($re->kwd_referer);
|
1569 |
+
$arr[$c]['hit_search_words'] = $re->kwd_keywords;
|
1570 |
+
$arr[$c]['hit_date'] = $re->kwd_date;
|
1571 |
+
$arr[$c]['hit_time'] = $re->kwd_time;
|
1572 |
+
$arr[$c]['hit_ip_address'] = $re->kwd_ip_address;
|
1573 |
+
$arr[$c]['ctr_name'] = $re->ctr_name;
|
1574 |
+
$arr[$c]['ctr_internet_code'] = $re->ctr_internet_code;
|
1575 |
+
$arr[$c]['bsr_name'] = $re->bsr_name;
|
1576 |
+
$arr[$c]['bsr_icon'] = $re->bsr_icon;
|
1577 |
+
$arr[$c]['srh_name'] = $re->srh_name;
|
1578 |
+
$arr[$c]['srh_icon'] = $re->srh_icon;
|
1579 |
+
$c++;
|
1580 |
+
}
|
1581 |
+
return $arr;
|
1582 |
+
} else {
|
1583 |
+
return false;
|
1584 |
+
}
|
1585 |
}
|
1586 |
+
|
1587 |
//--------------------------------------------
|
1588 |
/**
|
1589 |
* Is in login page
|
1590 |
*
|
1591 |
* @return boolean
|
1592 |
*/
|
1593 |
+
function ahcfree_is_login_page() {
|
1594 |
+
global $Globalsahcfree;
|
1595 |
+
|
1596 |
+
return in_array($Globalsahcfree['pagenow'], array('wp-login.php', 'wp-register.php'));
|
1597 |
+
}
|
1598 |
+
|
1599 |
+
//--------------------------------------------
|
1600 |
+
/**
|
1601 |
+
* Retrieves today visitors data, for google map
|
1602 |
+
*
|
1603 |
+
* @uses wpdb::get_results()
|
1604 |
+
*
|
1605 |
+
* @return array
|
1606 |
+
*/
|
1607 |
+
function ahcfree_get_today_visitors_for_map() {
|
1608 |
+
global $wpdb;
|
1609 |
+
$sql = "SELECT hits.visitors, hits.ctr_id,
|
1610 |
+
c.ctr_name, c.ctr_internet_code, c.ctr_latitude, c.ctr_longitude FROM (
|
1611 |
+
SELECT COUNT(v.visitor) AS visitors, v.ctr_id FROM (
|
1612 |
+
SELECT ctr_id, 1 AS visitor FROM `ahc_hits`
|
1613 |
+
WHERE ctr_id IS NOT NULL AND hit_ip_address NOT LIKE 'UNKNOWN%'
|
1614 |
+
GROUP BY hit_ip_address
|
1615 |
+
) AS v
|
1616 |
+
GROUP BY ctr_id) AS hits
|
1617 |
+
JOIN `ahc_countries` AS c ON hits.ctr_id = c.ctr_id
|
1618 |
+
WHERE c.ctr_latitude IS NOT NULL AND c.ctr_latitude <> 0 AND c.ctr_longitude IS NOT NULL AND c.ctr_longitude <> 0";
|
1619 |
+
|
1620 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
1621 |
+
$response = array();
|
1622 |
+
if ($results !== false) {
|
1623 |
+
$response['success'] = true;
|
1624 |
+
$response['data'] = array();
|
1625 |
+
if (is_array($results) && isset($results[0]->visitors) && !empty($results[0]->visitors)) {
|
1626 |
+
foreach ($results as $r) {
|
1627 |
+
$response['data'][$r->ctr_id]['visitors'] = $r->visitors;
|
1628 |
+
$response['data'][$r->ctr_id]['ctr_name'] = $r->ctr_name;
|
1629 |
+
$response['data'][$r->ctr_id]['ctr_internet_code'] = $r->ctr_internet_code;
|
1630 |
+
$response['data'][$r->ctr_id]['ctr_latitude'] = $r->ctr_latitude;
|
1631 |
+
$response['data'][$r->ctr_id]['ctr_longitude'] = $r->ctr_longitude;
|
1632 |
+
}
|
1633 |
+
}
|
1634 |
+
} else {
|
1635 |
+
$response['success'] = false;
|
1636 |
+
}
|
1637 |
+
return $response;
|
1638 |
+
}
|
1639 |
+
|
1640 |
+
/**
|
1641 |
+
* Retrieves online visitors data, for google map
|
1642 |
+
*
|
1643 |
+
* @uses wpdb::get_results()
|
1644 |
+
*
|
1645 |
+
* @return array
|
1646 |
+
*/
|
1647 |
+
function ahcfree_get_online_visitors_for_map() {
|
1648 |
+
global $wpdb;
|
1649 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1650 |
+
$sql = "SELECT hits.visitors, hits.ctr_id,
|
1651 |
+
c.ctr_name, c.ctr_internet_code, c.ctr_latitude, c.ctr_longitude FROM (
|
1652 |
+
SELECT COUNT(v.visitor) AS visitors, v.ctr_id FROM (
|
1653 |
+
SELECT ctr_id, 1 AS visitor FROM `ahc_hits`
|
1654 |
+
WHERE ctr_id IS NOT NULL AND hit_ip_address NOT LIKE 'UNKNOWN%' and hit_date = DATE( CONVERT_TZ( '". date("Y-m-d H:i:s") ."' ,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') ) and TIME( CONVERT_TZ(hit_time,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') ) between TIME(CONVERT_TZ('". date("Y-m-d H:i:s") ."','" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') - INTERVAL 60 SECOND) and TIME( CONVERT_TZ('". date("Y-m-d H:i:s") ."','" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "') )
|
1655 |
+
GROUP BY hit_ip_address
|
1656 |
+
) AS v
|
1657 |
+
GROUP BY ctr_id) AS hits
|
1658 |
+
JOIN `ahc_countries` AS c ON hits.ctr_id = c.ctr_id
|
1659 |
+
WHERE c.ctr_latitude IS NOT NULL AND c.ctr_latitude <> 0 AND c.ctr_longitude IS NOT NULL AND c.ctr_longitude <> 0 ";
|
1660 |
+
|
1661 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
1662 |
+
$response = array();
|
1663 |
+
if ($results !== false) {
|
1664 |
+
$response['success'] = true;
|
1665 |
+
$response['data'] = array();
|
1666 |
+
if (is_array($results) && isset($results[0]->visitors) && !empty($results[0]->visitors)) {
|
1667 |
+
foreach ($results as $r) {
|
1668 |
+
$response['data'][$r->ctr_id]['visitors'] = $r->visitors;
|
1669 |
+
$response['data'][$r->ctr_id]['ctr_name'] = $r->ctr_name;
|
1670 |
+
$response['data'][$r->ctr_id]['ctr_internet_code'] = $r->ctr_internet_code;
|
1671 |
+
$response['data'][$r->ctr_id]['ctr_latitude'] = $r->ctr_latitude;
|
1672 |
+
$response['data'][$r->ctr_id]['ctr_longitude'] = $r->ctr_longitude;
|
1673 |
+
}
|
1674 |
+
}
|
1675 |
+
} else {
|
1676 |
+
$response['success'] = false;
|
1677 |
+
}
|
1678 |
+
return $response;
|
1679 |
}
|
1680 |
+
|
1681 |
//--------------------------------------------
|
1682 |
/**
|
1683 |
* Detect if the visitor is search engine bot
|
1685 |
* @uses wpdb::get_results()
|
1686 |
*
|
1687 |
* @return boolean
|
1688 |
+
*/
|
1689 |
+
function ahcfree_is_search_engine_bot() {
|
1690 |
+
global $wpdb, $_SERVER;
|
1691 |
+
$results = $wpdb->get_results("SELECT `bot_name` FROM `ahc_search_engine_crawlers`", OBJECT);
|
1692 |
+
foreach ($results as $crawler) {
|
1693 |
+
if (stripos($_SERVER['HTTP_USER_AGENT'], $crawler->bot_name) !== false) {
|
1694 |
+
return true;
|
1695 |
+
}
|
1696 |
+
}
|
1697 |
+
|
1698 |
+
if (stripos($_SERVER['REQUEST_URI'], 'robots.txt') !== false) {
|
1699 |
+
return true;
|
1700 |
+
}
|
1701 |
+
|
1702 |
+
if (stripos($_SERVER['REQUEST_URI'], 'Bot') !== false) {
|
1703 |
+
return true;
|
1704 |
+
}
|
1705 |
+
|
1706 |
+
if (stripos($_SERVER['REQUEST_URI'], 'bot') !== false) {
|
1707 |
+
return true;
|
1708 |
+
}
|
1709 |
+
return false;
|
1710 |
}
|
1711 |
+
|
1712 |
//--------------------------------------------
|
1713 |
/**
|
1714 |
* Detect if the visitor is WordPress bot
|
1715 |
*
|
1716 |
* @return boolean
|
1717 |
*/
|
1718 |
+
function ahcfree_is_wordpress_bot() {
|
1719 |
+
global $_SERVER;
|
1720 |
+
if (stripos($_SERVER['HTTP_USER_AGENT'], 'WordPress') !== false) {
|
1721 |
+
return true;
|
1722 |
+
}
|
1723 |
+
return false;
|
1724 |
}
|
1725 |
+
|
1726 |
//--------------------------------------------
|
1727 |
/**
|
1728 |
* Detects post id, post title and post type of current page
|
1733 |
* @param object $query. this object is passed to the callback function of "parse_query" hooked action
|
1734 |
* @return mixed
|
1735 |
*/
|
1736 |
+
function ahcfree_detect_requested_page($query) {
|
1737 |
+
global $wpdb;
|
1738 |
+
$vars = $query->query_vars;
|
1739 |
+
if (isset($vars['p']) && !empty($vars['p'])) {
|
1740 |
+
$result = $wpdb->get_results($wpdb->prepare("SELECT post_title FROM " . $wpdb->prefix . "posts WHERE ID = %d ", $vars['p']));
|
1741 |
+
if ($result !== false && $wpdb->num_rows > 0) {
|
1742 |
+
return array('page_id' => $vars['p'], 'page_title' => $result[0]->post_title, 'post_type' => 'post');
|
1743 |
+
}
|
1744 |
+
} else if (isset($vars['name']) && !empty($vars['name'])) {
|
1745 |
+
$result = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title FROM " . $wpdb->prefix . "posts WHERE post_name = %s ", $vars['name']));
|
1746 |
+
if ($result !== false && $wpdb->num_rows > 0) {
|
1747 |
+
return array('page_id' => $result[0]->ID, 'page_title' => $result[0]->post_title, 'post_type' => 'post');
|
1748 |
+
}
|
1749 |
+
} else if (isset($vars['pagename']) && !empty($vars['pagename'])) {
|
1750 |
+
$result = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title FROM " . $wpdb->prefix . "posts WHERE post_name = %s AND post_type = %s", ahcfree_get_subpage_name($vars['pagename']), 'page'));
|
1751 |
+
if ($result !== false && $wpdb->num_rows > 0) {
|
1752 |
+
return array('page_id' => $result[0]->ID, 'page_title' => $result[0]->post_title, 'post_type' => 'page');
|
1753 |
+
}
|
1754 |
+
} else if (isset($vars['page_id']) && !empty($vars['page_id'])) {
|
1755 |
+
$result = $wpdb->get_results($wpdb->prepare("SELECT post_title FROM " . $wpdb->prefix . "posts WHERE ID = %s AND post_type = %s", $vars['page_id'], 'page'));
|
1756 |
+
if ($result !== false && $wpdb->num_rows > 0) {
|
1757 |
+
return array('page_id' => $page_id, 'page_title' => $result[0]->post_title, 'post_type' => 'page');
|
1758 |
+
}
|
1759 |
+
} else {
|
1760 |
+
return array('page_id' => 'HOMEPAGE', 'page_title' => NULL, 'post_type' => NULL);
|
1761 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1762 |
}
|
1763 |
|
1764 |
+
function ahcfree_get_subpage_name($page_name) {
|
1765 |
+
$sub_name = strrchr($page_name, '/');
|
1766 |
+
if (!$sub_name) {
|
1767 |
+
return $page_name;
|
1768 |
+
}
|
1769 |
+
return substr($sub_name, 1);
|
1770 |
}
|
1771 |
+
|
1772 |
//--------------------------------------------
|
1773 |
+
function ahcfree_sanitizing($unsafe_val,$type='text')
|
1774 |
+
{
|
1775 |
+
|
1776 |
+
|
1777 |
+
switch ($type) {
|
1778 |
+
case 'text': return sanitize_text_field($unsafe_val);
|
1779 |
+
break;
|
1780 |
+
|
1781 |
+
case 'int': return intval($unsafe_val);
|
1782 |
+
break;
|
1783 |
+
|
1784 |
+
case 'email': return sanitize_email($unsafe_val);
|
1785 |
+
break;
|
1786 |
+
|
1787 |
+
case 'filename': return sanitize_file_name($unsafe_val);
|
1788 |
+
break;
|
1789 |
+
|
1790 |
+
case 'title': return sanitize_title($unsafe_val);
|
1791 |
+
break;
|
1792 |
+
|
1793 |
+
case 'url': return esc_url($unsafe_val);
|
1794 |
+
break;
|
1795 |
+
|
1796 |
+
default:
|
1797 |
+
return sanitize_text_field($unsafe_val);
|
1798 |
+
|
1799 |
+
}
|
1800 |
+
}
|
1801 |
+
|
1802 |
+
|
1803 |
+
function ahcfree_track_visitor()
|
1804 |
+
{
|
1805 |
+
$exclude_ips = AHCFREE_EXCLUDE_IPS;
|
1806 |
+
if ($exclude_ips == '' or $exclude_ips == '') {
|
1807 |
+
$exclude_ips = array();
|
1808 |
+
}
|
1809 |
+
if (AHCFREE_EXCLUDE_IPS != NULL && AHCFREE_EXCLUDE_IPS != '') {
|
1810 |
+
$exclude_ips = explode("\n", $exclude_ips);
|
1811 |
+
}
|
1812 |
+
|
1813 |
+
if (ahcfree_should_track_visitor() && !ahcfree_is_login_page() && !ahcfree_is_search_engine_bot() && !ahcfree_is_wordpress_bot()) {
|
1814 |
+
if (!in_array(ahcfree_get_client_ip_address(), $exclude_ips)) {
|
1815 |
+
|
1816 |
+
$page_id = ahcfree_sanitizing($_POST['page_id'], 'int');
|
1817 |
+
$page_title = ahcfree_sanitizing($_POST['page_title']);
|
1818 |
+
$post_type = ahcfree_sanitizing($_POST['post_type']);
|
1819 |
+
$_SERVER['HTTP_REFERER'] = ahcfree_sanitizing($_POST['referer']);
|
1820 |
+
$_SERVER['HTTP_USER_AGENT'] = ahcfree_sanitizing($_POST['useragent']);
|
1821 |
+
$_SERVER['SERVER_NAME'] = ahcfree_sanitizing($_POST['servername']);
|
1822 |
+
$_SERVER['HTTP_HOST'] = ahcfree_sanitizing($_POST['hostname']);
|
1823 |
+
$_SERVER['REQUEST_URI'] = ahcfree_sanitizing($_POST['request_uri']);
|
1824 |
+
|
1825 |
+
$hitsCounter = new AHCFree_WPHitsCounterPro($page_id, $page_title, $post_type);
|
1826 |
+
$hitsCounter->traceVisitorHit();
|
1827 |
+
}
|
1828 |
+
}
|
1829 |
+
|
1830 |
+
die;
|
1831 |
}
|
1832 |
+
|
1833 |
+
|
1834 |
+
|
1835 |
//--------------------------------------------
|
1836 |
/**
|
1837 |
* Ceil for decimal numbers with precision
|
1841 |
* @param string $separator
|
1842 |
* @return float
|
1843 |
*/
|
1844 |
+
function ahcfree_ceil_dec($number, $precision, $separator) {
|
1845 |
+
if (strpos($number, '.') !== false) {
|
1846 |
+
$numberpart = explode($separator, $number);
|
1847 |
+
$numberpart[1] = substr_replace($numberpart[1], $separator, $precision, 0);
|
1848 |
+
if ($numberpart[0] >= 0) {
|
1849 |
+
$numberpart[1] = ceil($numberpart[1]);
|
1850 |
+
} else {
|
1851 |
+
$numberpart[1] = floor($numberpart[1]);
|
1852 |
+
}
|
1853 |
+
|
1854 |
+
$ceil_number = array($numberpart[0], $numberpart[1]);
|
1855 |
+
return implode($separator, $ceil_number);
|
1856 |
+
}
|
1857 |
+
return $number;
|
1858 |
}
|
1859 |
+
|
1860 |
//--------------------------------------------
|
1861 |
/**
|
1862 |
* Retrieve sum visits by post title
|
1866 |
*
|
1867 |
* @return mixed
|
1868 |
*/
|
1869 |
+
function ahcfree_get_traffic_by_title() {
|
1870 |
+
global $wpdb;
|
1871 |
+
$sql1 = "SELECT SUM(hits) AS sm FROM (
|
1872 |
SELECT SUM(til_hits) AS hits
|
1873 |
FROM ahc_title_traffic
|
1874 |
GROUP BY til_page_id
|
1875 |
) myTable";
|
1876 |
+
|
1877 |
+
$sql2 = "SELECT til_page_id, til_page_title, til_hits
|
1878 |
FROM ahc_title_traffic
|
1879 |
GROUP BY til_page_id
|
1880 |
ORDER BY til_hits DESC
|
1881 |
LIMIT %d OFFSET 0";
|
1882 |
+
|
1883 |
+
$result1 = $wpdb->get_results($sql1);
|
1884 |
+
if ($result1 !== false) {
|
1885 |
+
$total = $result1[0]->sm;
|
1886 |
+
$result2 = $wpdb->get_results($wpdb->prepare($sql2, AHCFREE_TRAFFIC_BY_TITLE_LIMIT));
|
1887 |
+
if ($result2 !== false) {
|
1888 |
+
$arr = array();
|
1889 |
+
if ($wpdb->num_rows > 0) {
|
1890 |
+
$c = 0;
|
1891 |
+
foreach ($result2 as $r) {
|
1892 |
+
$arr[$c]['rank'] = $c + 1;
|
1893 |
+
$arr[$c]['til_page_id'] = $r->til_page_id;
|
1894 |
+
$arr[$c]['til_page_title'] = $r->til_page_title;
|
1895 |
+
$arr[$c]['til_hits'] = $r->til_hits;
|
1896 |
+
$arr[$c]['percent'] = ($total > 0) ? ahcfree_ceil_dec((($r->til_hits / $total) * 100), 2, ".") . ' %' : 0;
|
1897 |
+
$c++;
|
1898 |
+
}
|
1899 |
+
}
|
1900 |
+
return $arr;
|
1901 |
+
}
|
1902 |
+
}
|
1903 |
+
return false;
|
1904 |
}
|
1905 |
+
|
1906 |
//--------------------------------------------
|
1907 |
/**
|
1908 |
* Retrieves sum of visits order by time
|
1911 |
*
|
1912 |
* @return mixed
|
1913 |
*/
|
1914 |
+
function ahcfree_get_time_visits() {
|
1915 |
+
global $wpdb;
|
1916 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
1917 |
+
|
1918 |
+
$vst_date = "CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')";
|
1919 |
+
$sql1 = "SELECT SUM(vtm_visitors) AS sm FROM ahc_visits_time WHERE DATE($vst_date) = '".date('Y-m-d')."'";
|
1920 |
+
$sql2 = "SELECT hour($vst_date) AS hour, SUM(vst_visitors) AS vst_visitors, SUM(vst_visits) AS vst_visits FROM `ahc_visitors`
|
1921 |
+
WHERE DATE($vst_date) = '".date('Y-m-d')."' GROUP BY hour($vst_date) ";
|
1922 |
+
//$result1 = $wpdb->get_results($sql1);
|
1923 |
+
//if ($result1 !== false) {
|
1924 |
+
$total = 0;
|
1925 |
+
$result2 = $wpdb->get_results($sql2);
|
1926 |
+
//asort($result2);
|
1927 |
+
$utc_data = array();
|
1928 |
+
|
1929 |
+
if ($result2 !== false) {
|
1930 |
+
$arr = array();
|
1931 |
+
$hourDetails = array();
|
1932 |
+
foreach ($result2 as $r) {
|
1933 |
+
$hourDetails[ $r->hour ] = array(
|
1934 |
+
'visitor' => $r->vst_visitors,
|
1935 |
+
'visits' => $r->vst_visits,
|
1936 |
+
);
|
1937 |
+
$total += $r->vst_visitors;
|
1938 |
+
}
|
1939 |
+
for( $i = 0; $i < 24; $i++ ){
|
1940 |
+
$vtm_visitors = 0;
|
1941 |
+
$vtm_visits = 0;
|
1942 |
+
if( isset( $hourDetails[$i] ) ){
|
1943 |
+
$vtm_visitors = $hourDetails[$i]['visitor'];
|
1944 |
+
$vtm_visits = $hourDetails[$i]['visits'];
|
1945 |
+
}
|
1946 |
+
if( $i < 10 ){
|
1947 |
+
$timeTo = $timeFrom = '0'.$i;
|
1948 |
+
}else{
|
1949 |
+
$timeTo = $timeFrom = $i;
|
1950 |
+
}
|
1951 |
+
$arr[$i]['vtm_time_from'] = $timeFrom.':00';
|
1952 |
+
$arr[$i]['vtm_time_to'] = $timeTo.':59';
|
1953 |
+
$arr[$i]['vtm_visitors'] = $vtm_visitors;
|
1954 |
+
$arr[$i]['vtm_visits'] = $vtm_visits;
|
1955 |
+
$arr[$i]['percent'] = ($total > 0) ? ahcfree_ceil_dec((($vtm_visitors / $total) * 100), 2, ".") : 0;
|
1956 |
}
|
1957 |
+
return $arr;
|
1958 |
+
}
|
1959 |
+
//}
|
1960 |
+
return false;
|
1961 |
+
|
1962 |
+
}
|
1963 |
+
|
1964 |
+
function ahcfree_advanced_get_link($url, $followRedirects = true) {
|
1965 |
+
$url_parsed = @parse_url($url);
|
1966 |
+
$header = '';
|
1967 |
+
$body = '';
|
1968 |
+
|
1969 |
+
if (empty($url_parsed['scheme'])) {
|
1970 |
+
$url_parsed = @parse_url($url);
|
1971 |
+
}
|
1972 |
+
$rtn['url'] = $url_parsed;
|
1973 |
+
|
1974 |
+
$port = $url_parsed["port"];
|
1975 |
+
if (!$port) {
|
1976 |
+
$port = 80;
|
1977 |
+
}
|
1978 |
+
$rtn['url']['port'] = $port;
|
1979 |
+
|
1980 |
+
$path = $url_parsed["path"];
|
1981 |
+
if (empty($path)) {
|
1982 |
+
$path = "/";
|
1983 |
+
}
|
1984 |
+
if (!empty($url_parsed["query"])) {
|
1985 |
+
$path .= "?" . $url_parsed["query"];
|
1986 |
+
}
|
1987 |
+
$rtn['url']['path'] = $path;
|
1988 |
+
|
1989 |
+
$host = $url_parsed["host"];
|
1990 |
+
$foundBody = false;
|
1991 |
+
|
1992 |
+
$out = "GET $path HTTP/1.0\r\n";
|
1993 |
+
$out .= "Host: $host\r\n";
|
1994 |
+
$out .= "Connection: Close\r\n\r\n";
|
1995 |
+
|
1996 |
+
if (!$fp = @fsockopen($host, $port, $errno, $errstr, 30)) {
|
1997 |
+
$rtn['errornumber'] = $errno;
|
1998 |
+
$rtn['errorstring'] = $errstr;
|
1999 |
+
return $rtn;
|
2000 |
+
}
|
2001 |
+
fwrite($fp, $out);
|
2002 |
+
while (!feof($fp)) {
|
2003 |
+
$s = fgets($fp, 128);
|
2004 |
+
if ($s == "\r\n") {
|
2005 |
+
$foundBody = true;
|
2006 |
+
continue;
|
2007 |
+
}
|
2008 |
+
if ($foundBody) {
|
2009 |
+
$body .= $s;
|
2010 |
+
} else {
|
2011 |
+
if (($followRedirects) && (stristr($s, "location:") != false)) {
|
2012 |
+
$redirect = preg_replace("/location:/i", "", $s);
|
2013 |
+
return ffl_HttpGet(trim($redirect));
|
2014 |
+
}
|
2015 |
+
$header .= $s;
|
2016 |
+
}
|
2017 |
+
}
|
2018 |
+
fclose($fp);
|
2019 |
+
|
2020 |
+
$rtn['header'] = trim($header);
|
2021 |
+
$rtn['body'] = trim($body);
|
2022 |
+
return $rtn;
|
2023 |
}
|
2024 |
+
|
2025 |
//--------------------------------------------
|
2026 |
/**
|
2027 |
* Returns client IP address
|
2028 |
*
|
2029 |
* @return string
|
2030 |
*/
|
2031 |
+
function ahcfree_get_client_ip_address() {
|
2032 |
+
global $_SERVER;
|
2033 |
+
$ipAddress = '';
|
2034 |
+
if (isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR']!='127.0.0.1') {
|
2035 |
+
$ipAddress = $_SERVER['REMOTE_ADDR'];
|
2036 |
+
}else if (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP']!='127.0.0.1') {
|
2037 |
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
|
2038 |
+
} else if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']!='127.0.0.1') {
|
|
|
2039 |
$ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
2040 |
+
} else if (isset($_SERVER['HTTP_X_FORWARDED']) && !empty($_SERVER['HTTP_X_FORWARDED']) && $_SERVER['HTTP_X_FORWARDED']!='127.0.0.1') {
|
|
|
2041 |
$ipAddress = $_SERVER['HTTP_X_FORWARDED'];
|
2042 |
+
} else if (isset($_SERVER['HTTP_FORWARDED_FOR']) && !empty($_SERVER['HTTP_FORWARDED_FOR']) && $_SERVER['HTTP_FORWARDED_FOR']!='127.0.0.1') {
|
|
|
2043 |
$ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
|
2044 |
+
} else if (isset($_SERVER['HTTP_FORWARDED']) && !empty($_SERVER['HTTP_FORWARDED']) && $_SERVER['HTTP_FORWARDED']!='127.0.0.1') {
|
|
|
2045 |
$ipAddress = $_SERVER['HTTP_FORWARDED'];
|
2046 |
+
} else {
|
|
|
|
|
|
|
|
|
2047 |
$ipAddress = 'UNKNOWN';
|
2048 |
+
}
|
2049 |
+
|
2050 |
+
$ipAddress = explode(',', $ipAddress);
|
2051 |
+
|
2052 |
+
return $ipAddress[0];
|
2053 |
}
|
2054 |
+
|
2055 |
//--------------------------------------------
|
2056 |
/**
|
2057 |
* To include scripts and styles tags into the head
|
2063 |
*
|
2064 |
* @return void
|
2065 |
*/
|
2066 |
+
function ahcfree_include_scripts() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2067 |
|
2068 |
|
2069 |
+
wp_register_style('ahcfree_lang_css', plugins_url('/css/engl_css.css', AHCFREE_PLUGIN_MAIN_FILE));
|
2070 |
+
wp_enqueue_style('ahcfree_lang_css');
|
2071 |
+
|
2072 |
+
if(get_locale() == 'ar')
|
2073 |
+
{
|
2074 |
+
wp_register_style('ahcfree_bootstrap_ar_css', plugins_url('/lib/bootstrap/css/bootstrap-rtl.min.css',AHCFREE_PLUGIN_MAIN_FILE));
|
2075 |
+
wp_enqueue_style('ahcfree_bootstrap_ar_css');
|
2076 |
+
}else{
|
2077 |
+
wp_register_style('ahcfree_bootstrap_css', plugins_url('/lib/bootstrap/css/bootstrap.min.css',AHCFREE_PLUGIN_MAIN_FILE));
|
2078 |
+
wp_enqueue_style('ahcfree_bootstrap_css');
|
2079 |
+
}
|
2080 |
+
|
2081 |
+
wp_enqueue_script( 'ahc_slimselect_js', 'https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.25.0/slimselect.min.js', false, '1.0.0', false);
|
2082 |
+
wp_register_style('ahc_slimselect_css', 'https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.25.0/slimselect.min.css', false, '1.0.0' );
|
2083 |
+
wp_enqueue_style('ahc_slimselect_css');
|
2084 |
+
wp_enqueue_script('jquery');
|
2085 |
+
|
2086 |
+
wp_register_script('ahcfree_bootstrap_js', plugins_url('/lib/bootstrap/js/bootstrap.min.js',AHCFREE_PLUGIN_MAIN_FILE));
|
2087 |
+
wp_enqueue_script('ahcfree_bootstrap_js');
|
2088 |
+
|
2089 |
+
wp_register_script('ahcfree_lang_js', plugins_url('/lang/js/' . Globalsahcfree::$lang . '_lang.js', AHCFREE_PLUGIN_MAIN_FILE));
|
2090 |
+
wp_enqueue_script('ahcfree_lang_js');
|
2091 |
+
|
2092 |
+
wp_register_script('ahcfree_main_js', plugins_url('/js/ahc_jqscripts.js', AHCFREE_PLUGIN_MAIN_FILE), false, '1.19');
|
2093 |
+
wp_enqueue_script('ahcfree_main_js');
|
2094 |
+
|
2095 |
+
wp_localize_script('ahcfree_main_js', 'ahcfree_ajax', array('ajax_url' => admin_url('admin-ajax.php')));
|
2096 |
+
|
2097 |
+
wp_register_script('ahcfree_Chart_js', plugins_url('/lib/Chart_js/Chart.min.js', AHCFREE_PLUGIN_MAIN_FILE));
|
2098 |
+
wp_enqueue_script('ahcfree_Chart_js');
|
2099 |
+
|
2100 |
+
wp_register_script('utils_js', plugins_url('/lib/Chart_js/utils.js', AHCFREE_PLUGIN_MAIN_FILE));
|
2101 |
+
wp_enqueue_script('utils_js');
|
2102 |
+
|
2103 |
+
|
2104 |
+
/* wp_register_script('ahcfree_GoogleChart_js', 'https://www.gstatic.com/charts/loader.js');
|
2105 |
+
wp_enqueue_script('ahcfree_GoogleChart_js');
|
2106 |
+
|
2107 |
+
*/
|
2108 |
+
// jqplot
|
2109 |
+
wp_register_style('jqueryjqplotmincss', plugins_url('/css/jquery.jqplot.min.css?ver=1.0.8', AHCFREE_PLUGIN_MAIN_FILE));
|
2110 |
+
wp_enqueue_style('jqueryjqplotmincss');
|
2111 |
+
|
2112 |
+
wp_register_script('jqueryjqplotmin', plugins_url('/js/jquery.jqplot.min.js?ver=0.8.3', AHCFREE_PLUGIN_MAIN_FILE));
|
2113 |
+
wp_enqueue_script('jqueryjqplotmin');
|
2114 |
+
|
2115 |
+
wp_register_script('jqplotdateAxisRenderermin', plugins_url('/js/jqplot.dateAxisRenderer.min.js?ver=0.8.3', AHCFREE_PLUGIN_MAIN_FILE));
|
2116 |
+
wp_enqueue_script('jqplotdateAxisRenderermin');
|
2117 |
+
|
2118 |
+
wp_register_script('jqplotcanvasAxisTickRenderermin', plugins_url('/js/jqplot.canvasAxisTickRenderer.min.js?ver=0.8.3', AHCFREE_PLUGIN_MAIN_FILE));
|
2119 |
+
wp_enqueue_script('jqplotcanvasAxisTickRenderermin');
|
2120 |
+
|
2121 |
+
wp_register_script('jqplotcanvasAxisLabelRenderermin', plugins_url('/js/jqplot.canvasAxisLabelRenderer.min.js?ver=0.8.3', AHCFREE_PLUGIN_MAIN_FILE));
|
2122 |
+
wp_enqueue_script('jqplotcanvasAxisLabelRenderermin');
|
2123 |
+
|
2124 |
+
wp_register_script('jqplot.canvasTextRenderer.min', plugins_url('/js/jqplot.canvasTextRenderer.min.js?ver=0.8.3', AHCFREE_PLUGIN_MAIN_FILE));
|
2125 |
+
wp_enqueue_script('jqplot.canvasTextRenderer.min');
|
2126 |
+
|
2127 |
+
|
2128 |
|
2129 |
+
wp_register_script('jqplothighlightermin', plugins_url('/js/jqplot.highlighter.min.js?ver=0.8.3', AHCFREE_PLUGIN_MAIN_FILE));
|
2130 |
+
wp_enqueue_script('jqplothighlightermin');
|
2131 |
|
2132 |
+
wp_register_script('jqplot.pieRenderer.min', plugins_url('/js/jqplot.pieRenderer.min.js?ver=0.8.3', AHCFREE_PLUGIN_MAIN_FILE));
|
2133 |
+
wp_enqueue_script('jqplot.pieRenderer.min');
|
2134 |
|
2135 |
+
wp_register_script('jqplot.enhancedLegendRenderer.min', plugins_url('/js/jqplot.enhancedLegendRenderer.min.js?ver=0.8.3', AHCFREE_PLUGIN_MAIN_FILE));
|
2136 |
+
wp_enqueue_script('jqplot.enhancedLegendRenderer.min');
|
2137 |
+
|
2138 |
+
wp_enqueue_script('sweetalert', plugins_url('/js/sweetalert.min.js', AHCFREE_PLUGIN_MAIN_FILE));
|
2139 |
+
wp_enqueue_style( 'sweetalert', plugins_url('/css/sweetalerts.css', AHCFREE_PLUGIN_MAIN_FILE));
|
2140 |
+
|
2141 |
+
|
2142 |
+
|
2143 |
+
|
2144 |
+
}
|
2145 |
+
|
2146 |
+
//--------------------------------------------
|
2147 |
//---------------------------------------------Add button to the admin bar
|
2148 |
+
function ahcfree_vtrts_add_items($admin_bar) {
|
2149 |
+
global $pluginsurl;
|
|
|
2150 |
|
2151 |
+
$wccpadminurl = get_admin_url();
|
2152 |
//The properties of the new item. Read More about the missing 'parent' parameter below
|
2153 |
$args = array(
|
2154 |
+
'id' => 'visitorstraffic',
|
2155 |
+
'title' => __('<img src="' . plugins_url('/images/vtrtspro.png', AHCFREE_PLUGIN_MAIN_FILE) . '" style="vertical-align:middle;margin-right:5px;" alt="visitor traffic" title="visitor traffic" />'),
|
2156 |
+
'href' => $wccpadminurl . 'admin.php?page=ahc_hits_counter_menu_free',
|
2157 |
+
'meta' => array('title' => __('Visitor Traffic Real Time Statistics'),)
|
2158 |
+
);
|
2159 |
+
|
2160 |
//This is where the magic works.
|
2161 |
+
$admin_bar->add_menu($args);
|
2162 |
}
|
2163 |
+
|
2164 |
//---------------------------------------- Add plugin settings link to Plugins page
|
2165 |
+
function ahcfree_vtrtsp_plugin_add_settings_link($links) {
|
2166 |
+
$settings_link = '<a href="admin.php?page=ahc_hits_counter_menu_pro">' . __('visitor traffic') . '</a>';
|
2167 |
+
array_push($links, $settings_link);
|
2168 |
+
return $links;
|
2169 |
}
|
2170 |
+
|
2171 |
//------------------------------------------------------------------------
|
2172 |
+
// --------------------------------------- Create front-end widget
|
2173 |
+
// Creating the widget
|
2174 |
+
class vtrtsfree_widget extends WP_Widget {
|
2175 |
|
2176 |
+
function __construct() {
|
2177 |
+
parent::__construct(
|
2178 |
+
// Base ID of your widget
|
2179 |
+
'vtrtsfree_widget',
|
2180 |
+
// Widget name will appear in UI
|
2181 |
+
__('Visitor Traffic', 'wpb_widget_domain'),
|
2182 |
+
// Widget description
|
2183 |
+
array('description' => __('Display your site statistics', 'wpb_widget_domain'),)
|
2184 |
+
);
|
2185 |
+
}
|
2186 |
|
2187 |
+
// Creating widget front-end
|
2188 |
+
// This is where the action happens
|
2189 |
+
public function widget($args, $instance) {
|
2190 |
+
$title = apply_filters('widget_title', $instance['title']);
|
2191 |
+
// before and after widget arguments are defined by themes
|
2192 |
+
echo $args['before_widget'];
|
2193 |
+
if (!empty($title))
|
2194 |
+
echo $args['before_title'] . $title . $args['after_title'];
|
2195 |
|
2196 |
|
2197 |
+
$ahcfree_sum_stats = ahcfree_get_summary_statistics();
|
2198 |
+
|
2199 |
+
|
2200 |
+
// This is where you run the code and display the output
|
2201 |
+
echo '<ul style="list-style:none; ' . $instance['fontTypeCombo'] . '; font-size:' . $instance['fontSizeCombo'] . 'px">';
|
2202 |
+
if ($instance['display_onlineusers'] == 1 or $instance['display_onlineusers'] == '1') {
|
2203 |
+
$online_img_path = plugins_url('/images/live.gif', AHCFREE_PLUGIN_MAIN_FILE);
|
2204 |
+
echo '<li><b style="color:#' . $instance['display_titlecolor'] . '">Users online: </b><span style="color:#' . $instance['display_valuescolor'] . '">' . ahcfree_countOnlineusers() . '</span> <img src="' . $online_img_path . '" /></li>';
|
2205 |
+
}
|
2206 |
+
if ($instance['display_visitorstoday'] == 1 or $instance['display_visitorstoday'] == '1') {
|
2207 |
+
echo '<li><b style="color:#' . $instance['display_titlecolor'] . '">Visitors today : </b><span style="color:#' . $instance['display_valuescolor'] . '">' . ahcfree_free_NumFormat($ahcfree_sum_stats['today']['visitors']) . '</span></li>';
|
2208 |
+
}
|
2209 |
+
if ($instance['display_pageviewtoday'] == 1 or $instance['display_pageviewtoday'] == '1') {
|
2210 |
+
echo '<li><b style="color:#' . $instance['display_titlecolor'] . '">Page views today : </b><span style="color:#' . $instance['display_valuescolor'] . '">' . ahcfree_free_NumFormat($ahcfree_sum_stats['today']['visits']) . '</span></li>';
|
2211 |
+
}
|
2212 |
+
|
2213 |
+
if ($instance['display_totalvisitors'] == 1 or $instance['display_totalvisitors'] == '1') {
|
2214 |
+
echo '<li><b style="color:#' . $instance['display_titlecolor'] . '">Total visitors : </b><span style="color:#' . $instance['display_valuescolor'] . '">' . ahcfree_free_NumFormat($ahcfree_sum_stats['total']['visitors']) . '</span></li>';
|
2215 |
+
}
|
2216 |
+
|
2217 |
+
if ($instance['display_totalpageview'] == 1 or $instance['display_totalpageview'] == '1') {
|
2218 |
+
echo '<li><b style="color:#' . $instance['display_titlecolor'] . '">Total page view: </b><span style="color:#' . $instance['display_valuescolor'] . '">' . ahcfree_free_NumFormat($ahcfree_sum_stats['total']['visits']) . '</span></li>';
|
2219 |
+
}
|
2220 |
+
|
2221 |
+
|
2222 |
+
echo '</ul>';
|
2223 |
+
echo $args['after_widget'];
|
2224 |
+
}
|
2225 |
+
|
2226 |
+
// Widget Backend
|
2227 |
+
public function form($instance) {
|
2228 |
+
extract($instance);
|
2229 |
+
|
2230 |
+
if (isset($instance['title'])) {
|
2231 |
+
$title = $instance['title'];
|
2232 |
+
} else {
|
2233 |
+
$title = __('Site Statistics', 'wpb_widget_domain');
|
2234 |
+
}
|
2235 |
+
// Widget admin form
|
2236 |
+
?>
|
2237 |
+
|
2238 |
+
|
2239 |
+
<p>
|
2240 |
+
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Widget Title:'); ?></label>
|
2241 |
+
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo (isset($title) ? esc_attr($title) : ''); ?>" />
|
2242 |
+
</p>
|
2243 |
+
|
2244 |
+
<p>
|
2245 |
+
<label for="<?php echo $this->get_field_id('display_titlecolor'); ?>"><?php _e('Title Color:'); ?></label>
|
2246 |
+
<input class="color widefat" id="<?php echo $this->get_field_id('display_titlecolor'); ?>" name="<?php echo $this->get_field_name('display_titlecolor'); ?>" style="border:#CCC solid 1px" value="<?php echo (isset($display_titlecolor) ? esc_attr($display_titlecolor) : ''); ?>" >
|
2247 |
+
</p>
|
2248 |
+
|
2249 |
+
<p>
|
2250 |
+
<label for="<?php echo $this->get_field_id('display_valuescolor'); ?>"><?php _e('Value Color:'); ?></label>
|
2251 |
+
<input class="color widefat" style="border:#CCC solid 1px" id="<?php echo $this->get_field_id('display_valuescolor'); ?>" name="<?php echo $this->get_field_name('display_valuescolor'); ?>" value="<?php echo (isset($display_valuescolor) ? esc_attr($display_valuescolor) : ''); ?>" >
|
2252 |
+
</p>
|
2253 |
+
|
2254 |
+
|
2255 |
+
<p>
|
2256 |
+
<label for="<?php echo $this->get_field_id('fontTypeCombo'); ?>"><?php _e('Font Type:'); ?></label>
|
2257 |
+
<select class="widefat" id="<?php echo $this->get_field_id('fontTypeCombo'); ?>" name="<?php echo $this->get_field_name('fontTypeCombo'); ?>">
|
2258 |
+
<optgroup class='verdana'>
|
2259 |
+
<option <?php selected($fontTypeCombo, 'font-family:Verdana, Geneva, sans-serif'); ?> value="font-family:Verdana, Geneva, sans-serif">Verdana</option>
|
2260 |
+
</optgroup>
|
2261 |
+
|
2262 |
+
<optgroup class='TimesNew'>
|
2263 |
+
<option <?php selected($fontTypeCombo, "font-family:'Times New Roman', Times, serif"); ?> value="font-family:'Times New Roman', Times, serif">Times New Roman</option>
|
2264 |
+
</optgroup>
|
2265 |
+
|
2266 |
+
<optgroup class='Arial'>
|
2267 |
+
<option <?php selected($fontTypeCombo, "font-family:Arial, Helvetica, sans-serif"); ?> value="font-family:Arial, Helvetica, sans-serif">Arial</option>
|
2268 |
+
</optgroup>
|
2269 |
+
|
2270 |
+
<optgroup class='Tahoma'>
|
2271 |
+
<option <?php selected($fontTypeCombo, "font-family:Tahoma, Geneva, sans-serif"); ?> value="font-family:Tahoma, Geneva, sans-serif">Tahoma</option>
|
2272 |
+
</optgroup>
|
2273 |
+
|
2274 |
+
<optgroup class='Courier'>
|
2275 |
+
<option <?php selected($fontTypeCombo, "font-family:'Courier New', Courier, monospace"); ?> value="font-family:'Courier New', Courier, monospace">Courier</option>
|
2276 |
+
</optgroup>
|
2277 |
+
|
2278 |
+
<optgroup class='TrebuchetMS'>
|
2279 |
+
<option <?php selected($fontTypeCombo, "font-family:'Trebuchet MS', Arial, Helvetica, sans-serif"); ?> value="font-family:'Trebuchet MS', Arial, Helvetica, sans-serif">Trebuchet MS</option>
|
2280 |
+
</optgroup>
|
2281 |
+
|
2282 |
+
|
2283 |
+
</select>
|
2284 |
+
|
2285 |
+
</p>
|
2286 |
+
<label for="<?php echo $this->get_field_id('fontSizeCombo'); ?>"><?php _e('Font Size:'); ?></label>
|
2287 |
+
<select class="widefat" id="<?php echo $this->get_field_id('fontSizeCombo'); ?>" name="<?php echo $this->get_field_name('fontSizeCombo'); ?>">
|
2288 |
+
<?php
|
2289 |
+
for ($fs = 8; $fs <= 22; $fs++) {
|
2290 |
+
?>
|
2291 |
+
<option value="<?php echo $fs ?>" <?php selected($fontSizeCombo, $fs); ?>><?php echo $fs; ?>px</option>
|
2292 |
+
<?php } ?>
|
2293 |
+
</select>
|
2294 |
+
<p>
|
2295 |
+
|
2296 |
+
</p>
|
2297 |
+
|
2298 |
+
<p><em>Display :</em></p>
|
2299 |
+
|
2300 |
+
|
2301 |
+
<p>
|
2302 |
+
<input class="widefat" id="<?php echo $this->get_field_id('display_onlineusers'); ?>" name="<?php echo $this->get_field_name('display_onlineusers'); ?>" type="checkbox" value="1" <?php isset($display_onlineusers) ? checked($display_onlineusers, '1') : ''; ?> /> <label for="<?php echo $this->get_field_id('display_onlineusers'); ?>">Users Online</label>
|
2303 |
+
</p>
|
2304 |
+
<p>
|
2305 |
+
<input class="widefat" id="<?php echo $this->get_field_id('display_visitorstoday'); ?>" name="<?php echo $this->get_field_name('display_visitorstoday'); ?>" type="checkbox" value="1" <?php isset($display_onlineusers) ? checked($display_visitorstoday, '1') : ''; ?>/> <label for="<?php echo $this->get_field_id('display_visitorstoday'); ?>">Visitors Today</label>
|
2306 |
+
</p>
|
2307 |
+
<p>
|
2308 |
+
<input class="widefat" id="<?php echo $this->get_field_id('display_pageviewtoday'); ?>" name="<?php echo $this->get_field_name('display_pageviewtoday'); ?>" type="checkbox" value="1" <?php isset($display_onlineusers) ? checked($display_pageviewtoday, '1') : ''; ?>/> <label for="<?php echo $this->get_field_id('display_pageviewtoday'); ?>">Page Views Today</label>
|
2309 |
+
</p>
|
2310 |
+
<p>
|
2311 |
+
<input class="widefat" id="<?php echo $this->get_field_id('display_totalpageview'); ?>" name="<?php echo $this->get_field_name('display_totalpageview'); ?>" type="checkbox" value="1" <?php isset($display_onlineusers) ? checked($display_totalpageview, '1') : ''; ?> /> <label for="<?php echo $this->get_field_id('display_totalpageview'); ?>">Total Page Views</label>
|
2312 |
+
</p>
|
2313 |
+
<p>
|
2314 |
+
<input class="widefat" id="<?php echo $this->get_field_id('display_totalvisitors'); ?>" name="<?php echo $this->get_field_name('display_totalvisitors'); ?>" type="checkbox" value="1" <?php isset($display_onlineusers) ? checked($display_totalvisitors, '1') : ''; ?>/> <label for="<?php echo $this->get_field_id('display_totalvisitors'); ?>">Total Visitors</label>
|
2315 |
+
</p>
|
2316 |
+
</p>
|
2317 |
+
<?php
|
2318 |
+
}
|
2319 |
+
|
2320 |
+
// Updating widget replacing old instances with new
|
2321 |
+
public function update($new_instance, $old_instance) {
|
2322 |
+
|
2323 |
+
return $new_instance;
|
2324 |
+
}
|
2325 |
+
|
2326 |
+
}
|
2327 |
+
|
2328 |
+
// Class vtrtsfree_widget ends here
|
2329 |
+
// Register and load the widget
|
2330 |
+
function ahcfree_wpb_load_widget() {
|
2331 |
+
register_widget('vtrtsfree_widget');
|
2332 |
+
}
|
2333 |
+
|
2334 |
+
add_action('widgets_init', 'ahcfree_wpb_load_widget');
|
2335 |
+
|
2336 |
+
function ahcfree_get_hits_by_custom_duration_callback(){
|
2337 |
+
$hits_duration = $_POST['hits_duration'];
|
2338 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
2339 |
+
$custom_timezone = new DateTimeZone(ahcfree_get_timezone_string());
|
2340 |
+
|
2341 |
+
$myend_date = new DateTime();
|
2342 |
+
$myend_date->setTimezone($custom_timezone);
|
2343 |
+
|
2344 |
+
$end_date = $myend_date->format('Y-m-d');
|
2345 |
+
$full_end_date = $myend_date->format('Y-m-d 23:59:59');
|
2346 |
+
|
2347 |
+
$mystart_date = new DateTime();
|
2348 |
+
$mystart_date->setTimezone($custom_timezone);
|
2349 |
+
$stat = '';
|
2350 |
+
switch ($hits_duration){
|
2351 |
+
|
2352 |
+
case '7':
|
2353 |
+
$mystart_date->modify('-7 days');
|
2354 |
+
$start_date = $mystart_date->format('Y-m-d');
|
2355 |
+
$full_start_date = $mystart_date->format('Y-m-d 00:00:00');
|
2356 |
+
$interval = '1 day';
|
2357 |
+
|
2358 |
+
break;
|
2359 |
+
|
2360 |
+
case 'current_month':
|
2361 |
+
//$mystart_date->modify('0:00 first day of curent month');
|
2362 |
+
$start_date = $mystart_date->format('Y-m-01');
|
2363 |
+
$end_date = $mystart_date->format('Y-m-t');
|
2364 |
+
$full_start_date = $mystart_date->format('Y-m-01');
|
2365 |
+
$full_end_date = $mystart_date->format('Y-m-t');
|
2366 |
+
$interval = '1 day';
|
2367 |
+
$stat = 'current_month';
|
2368 |
+
break;
|
2369 |
+
|
2370 |
+
case 'last_month':
|
2371 |
+
$mystart_date->modify('0:00 first day of previous month');
|
2372 |
+
$start_date = $mystart_date->format('Y-m-d');
|
2373 |
+
$end_date = $mystart_date->format('Y-m-t');
|
2374 |
+
$full_start_date = $mystart_date->format('Y-m-d');
|
2375 |
+
$full_end_date = $mystart_date->format('Y-m-t');
|
2376 |
+
$interval = '1 day';
|
2377 |
+
$stat = 'last_month';
|
2378 |
+
break;
|
2379 |
+
|
2380 |
+
case '30':
|
2381 |
+
/*$mystart_date->modify('first day of previous month');
|
2382 |
+
$start_date = $mystart_date->format('Y-m-d');
|
2383 |
+
$full_start_date = $mystart_date->format('Y-m-d H:i:s');
|
2384 |
+
|
2385 |
+
$myend_date->modify('last day of previous month');
|
2386 |
+
$end_date = $myend_date->format('Y-m-d');
|
2387 |
+
$full_end_date = $myend_date->format('Y-m-d H:i:s');*/
|
2388 |
+
|
2389 |
+
$mystart_date->modify('-30 days');
|
2390 |
+
$start_date = $mystart_date->format('Y-m-d');
|
2391 |
+
$full_start_date = $mystart_date->format('Y-m-d 00:00:00');
|
2392 |
+
|
2393 |
+
$interval = '1 week';
|
2394 |
+
break;
|
2395 |
+
|
2396 |
+
/* case '365':
|
2397 |
+
//$mystart_date->modify(' - 1 year');
|
2398 |
+
$start_date = (new DateTime(date("Y")."-01-01"))->format('Y-m-d');
|
2399 |
+
$full_start_date = (new DateTime(date("Y")."-01-01"))->format('Y-m-d 00:00:00');
|
2400 |
+
$end_date = $mystart_date->format('Y-m-t');
|
2401 |
+
$full_end_date = $mystart_date->format('Y-m-t 23:59:59');
|
2402 |
+
$interval = '1 month';
|
2403 |
+
$stat = 'year';
|
2404 |
+
break;
|
2405 |
+
*/
|
2406 |
+
|
2407 |
+
case '0':
|
2408 |
+
$full_start_date = $full_end_date = '';
|
2409 |
+
$stat = 'all';
|
2410 |
+
break;
|
2411 |
+
|
2412 |
+
default :
|
2413 |
+
$mystart_date->modify(' - ' . (AHC_VISITORS_VISITS_LIMIT - 1) . ' days');
|
2414 |
+
$start_date = $mystart_date->format('Y-m-d');
|
2415 |
+
$full_start_date = $mystart_date->format('Y-m-d 00:00:00');
|
2416 |
+
$interval = '1 day';
|
2417 |
+
break;
|
2418 |
+
}
|
2419 |
+
|
2420 |
+
$visits_visitors_data = ahcfree_get_visits_by_custom_duration_callback($full_start_date,$full_end_date,$stat);
|
2421 |
+
//print_r($visits_visitors_data);
|
2422 |
+
$response = array( 'mystart_date' => $start_date,
|
2423 |
+
'myend_date' => $end_date,
|
2424 |
+
'full_start_date' => $full_start_date,
|
2425 |
+
'full_end_date' => $full_end_date,
|
2426 |
+
'interval' => $interval,
|
2427 |
+
'visitors_data' => json_encode($visits_visitors_data['visitors']),
|
2428 |
+
'visits_data' => json_encode($visits_visitors_data['visits'])
|
2429 |
+
);
|
2430 |
+
|
2431 |
+
echo json_encode( $response );
|
2432 |
+
die;
|
2433 |
+
}
|
2434 |
+
|
2435 |
+
|
2436 |
+
function ahcfree_get_visits_by_custom_duration_callback( $start_date,$end_date,$stat){
|
2437 |
+
global $wpdb;
|
2438 |
+
$visits_arr = array();
|
2439 |
+
$custom_timezone_offset = ahcfree_get_current_timezone_offset();
|
2440 |
+
$custom_timezone = new DateTimeZone(ahcfree_get_timezone_string());
|
2441 |
+
|
2442 |
+
$results = false;
|
2443 |
+
|
2444 |
+
$mystart_date = new DateTime($start_date);
|
2445 |
+
$myend_date = new DateTime($end_date);
|
2446 |
+
|
2447 |
+
$total_days = date_diff( $mystart_date, $myend_date );
|
2448 |
+
$total_days = $total_days->format("%a");
|
2449 |
+
|
2450 |
+
$cond = "DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) >= DATE('". $start_date ." 00:00:00') AND DATE(CONVERT_TZ(vst_date, '" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "')) <= DATE('". $end_date ." 23:59:59')";
|
2451 |
+
|
2452 |
+
if($stat == 'year')
|
2453 |
+
{
|
2454 |
+
$sql = "SELECT DATE_FORMAT(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'),'%Y-%m') as group_date,DATE_FORMAT(CONVERT_TZ(vst_date,'".AHCFREE_SERVER_CURRENT_TIMEZONE."','".$custom_timezone_offset."'),'%Y-%m-01') as vst_date,SUM(vst_visitors) as vst_visitors,SUM(vst_visits) as vst_visits FROM ahc_visitors WHERE ". $cond." GROUP BY group_date";
|
2455 |
+
}
|
2456 |
+
if($stat == 'all')
|
2457 |
+
{
|
2458 |
+
$sql = "SELECT DATE_FORMAT(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "', '" . $custom_timezone_offset . "'),'%Y-%m') as group_date,DATE_FORMAT(CONVERT_TZ(vst_date,'".AHCFREE_SERVER_CURRENT_TIMEZONE."','".$custom_timezone_offset."'),'%Y-%m-01') as vst_date,SUM(vst_visitors) as vst_visitors,SUM(vst_visits) as vst_visits FROM ahc_visitors GROUP BY group_date ORDER BY vst_date ASC";
|
2459 |
+
|
2460 |
+
}
|
2461 |
+
if($stat == '' || $stat == 'current_month' || $stat == 'last_month' )
|
2462 |
+
{
|
2463 |
+
$sql = "SELECT DATE(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "')) as vst_date, SUM(vst_visits) AS vst_visits,SUM(vst_visitors) as vst_visitors FROM ahc_visitors WHERE ". $cond ." GROUP BY DATE(CONVERT_TZ(vst_date,'" . AHCFREE_SERVER_CURRENT_TIMEZONE . "','" . $custom_timezone_offset . "'))";
|
2464 |
+
}
|
2465 |
+
//echo $sql;
|
2466 |
+
$results = $wpdb->get_results($sql, OBJECT);
|
2467 |
+
if ($results !== false) {
|
2468 |
+
|
2469 |
+
if($stat == 'year')
|
2470 |
+
{
|
2471 |
+
for ($i = 1; $i <= date('n'); $i++) {
|
2472 |
+
$month = $mystart_date->format('m');
|
2473 |
+
$year = $mystart_date->format('Y');
|
2474 |
+
$total_days = cal_days_in_month(CAL_GREGORIAN, $month ,$year);
|
2475 |
|
2476 |
+
$visits_arr['visits'][] = array($mystart_date->format('Y-m-d'), 0);
|
2477 |
+
$visits_arr['visitors'][] = array($mystart_date->format('Y-m-d'), 0);
|
2478 |
+
$mystart_date->modify( '+'.$total_days.' days' );
|
2479 |
+
}
|
2480 |
+
}
|
2481 |
+
elseif($stat == 'all')
|
2482 |
+
{
|
2483 |
+
foreach($results as $key =>$element) {
|
2484 |
+
reset($results);
|
2485 |
+
if ($key === key($results)){
|
2486 |
+
$first_date = $element->vst_date;
|
2487 |
+
}
|
2488 |
+
|
2489 |
+
end($results);
|
2490 |
+
if ($key === key($results)){
|
2491 |
+
$last_date = $element->vst_date;
|
2492 |
+
}
|
2493 |
+
}
|
2494 |
+
|
2495 |
+
$d1 = new DateTime($first_date);
|
2496 |
+
$d2 = new DateTime($last_date);
|
2497 |
+
|
2498 |
+
if(count($results) == 1 )
|
2499 |
+
{
|
2500 |
+
$pre_d1 = new DateTime($first_date);
|
2501 |
+
$pre_d1->modify( 'first day of previous month' );
|
2502 |
+
$visits_arr['visits'][] = array($pre_d1->format( 'Y-m-d' ), 0);
|
2503 |
+
$visits_arr['visitors'][] = array($pre_d1->format( 'Y-m-d' ), 0);
|
2504 |
+
}
|
2505 |
+
|
2506 |
+
$diff = $d1->diff($d2)->m + 1;
|
2507 |
+
|
2508 |
+
for ($i = 1; $i <= $diff; $i++) {
|
2509 |
+
$visits_arr['visits'][] = array($d1->format('Y-m-d'), 0);
|
2510 |
+
$visits_arr['visitors'][] = array($d1->format('Y-m-d'), 0);
|
2511 |
+
$d1->modify( '+1 Month' );
|
|
|
|
|
|
|
|
|
|
|
2512 |
}
|
2513 |
+
}
|
2514 |
+
else
|
2515 |
+
{
|
2516 |
+
if($stat == 'current_month'){
|
2517 |
+
$total_days = date('t');
|
2518 |
+
$total_days--;
|
2519 |
+
}
|
2520 |
+
if($stat == 'last_month'){
|
2521 |
+
$total_days = date('t', strtotime('first day of previous month'));
|
2522 |
+
$total_days--;
|
2523 |
+
}
|
2524 |
+
$visits_arr['visits'][] = array($mystart_date->format('Y-m-d'), 0);
|
2525 |
+
$visits_arr['visitors'][] = array($mystart_date->format('Y-m-d'), 0);
|
2526 |
+
for ($i = 1; $i <= $total_days; $i++) {
|
2527 |
+
$mystart_date->modify( '+1 Day' );
|
2528 |
+
$visits_arr['visits'][] = array($mystart_date->format('Y-m-d'), 0);
|
2529 |
+
$visits_arr['visitors'][] = array($mystart_date->format('Y-m-d'), 0);
|
2530 |
+
}
|
2531 |
+
}
|
2532 |
+
//print_r($visits_arr['visits']);
|
2533 |
+
foreach( $visits_arr['visits'] as $key=>$visits ){
|
2534 |
+
foreach ($results as $r) {
|
2535 |
+
if( $visits[0] == $r->vst_date )
|
2536 |
+
{
|
2537 |
+
$visits_arr['visits'][$key][1] = $r->vst_visits;
|
2538 |
+
}
|
2539 |
+
}
|
2540 |
+
}
|
2541 |
+
|
2542 |
+
foreach( $visits_arr['visitors'] as $key=>$visits ){
|
2543 |
+
foreach ($results as $r) {
|
2544 |
+
if( $visits[0] == $r->vst_date )
|
2545 |
+
{
|
2546 |
+
$visits_arr['visitors'][$key][1] = $r->vst_visitors;
|
2547 |
+
}
|
2548 |
+
}
|
2549 |
+
}
|
2550 |
+
}
|
2551 |
+
//echo $wpdb->last_query;
|
2552 |
+
return $visits_arr;
|
2553 |
+
|
2554 |
+
}
|
2555 |
+
function ahcfree_admin_notice_to_set_timezone(){
|
2556 |
+
$class = 'notice notice-error';
|
2557 |
+
$name = 'Visitor Traffic Real Time Statistics free';
|
2558 |
+
$message = sprintf( __( 'Please set timezone from <a href="%s">here</a>' ), site_url('wp-admin/admin.php?page=ahc_hits_counter_settings') );
|
2559 |
+
|
2560 |
+
printf( '<div class="%1$s"><h3>%2$s</h3><p>%3$s</p></div>', esc_attr( $class ), $name, $message );
|
2561 |
+
|
2562 |
+
}
|
2563 |
+
?>
|
images/247.png
ADDED
Binary file
|
images/24_7.ico
ADDED
Binary file
|
images/Icon-user.png
ADDED
Binary file
|
images/Spinner-1s-200px.svg
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<svg class="lds-spinner" width="200px" height="200px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" style="background: none;"><g transform="rotate(0 50 50)">
|
2 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
3 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.9166666666666666s" repeatCount="indefinite"></animate>
|
4 |
+
</rect>
|
5 |
+
</g><g transform="rotate(30 50 50)">
|
6 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
7 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.8333333333333334s" repeatCount="indefinite"></animate>
|
8 |
+
</rect>
|
9 |
+
</g><g transform="rotate(60 50 50)">
|
10 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
11 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.75s" repeatCount="indefinite"></animate>
|
12 |
+
</rect>
|
13 |
+
</g><g transform="rotate(90 50 50)">
|
14 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
15 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.6666666666666666s" repeatCount="indefinite"></animate>
|
16 |
+
</rect>
|
17 |
+
</g><g transform="rotate(120 50 50)">
|
18 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
19 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5833333333333334s" repeatCount="indefinite"></animate>
|
20 |
+
</rect>
|
21 |
+
</g><g transform="rotate(150 50 50)">
|
22 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
23 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5s" repeatCount="indefinite"></animate>
|
24 |
+
</rect>
|
25 |
+
</g><g transform="rotate(180 50 50)">
|
26 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
27 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.4166666666666667s" repeatCount="indefinite"></animate>
|
28 |
+
</rect>
|
29 |
+
</g><g transform="rotate(210 50 50)">
|
30 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
31 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.3333333333333333s" repeatCount="indefinite"></animate>
|
32 |
+
</rect>
|
33 |
+
</g><g transform="rotate(240 50 50)">
|
34 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
35 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.25s" repeatCount="indefinite"></animate>
|
36 |
+
</rect>
|
37 |
+
</g><g transform="rotate(270 50 50)">
|
38 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
39 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.16666666666666666s" repeatCount="indefinite"></animate>
|
40 |
+
</rect>
|
41 |
+
</g><g transform="rotate(300 50 50)">
|
42 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
43 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.08333333333333333s" repeatCount="indefinite"></animate>
|
44 |
+
</rect>
|
45 |
+
</g><g transform="rotate(330 50 50)">
|
46 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
47 |
+
<animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animate>
|
48 |
+
</rect>
|
49 |
+
</g></svg>
|
images/VisualEditor_-_Icon_-_Search.svg.png
ADDED
Binary file
|
images/browsers_nodata.png
DELETED
Binary file
|
images/contact-center-reporting-icon.png
DELETED
Binary file
|
images/decrease.png
ADDED
Binary file
|
images/down.png
ADDED
Binary file
|
images/increase.png
ADDED
Binary file
|
images/latestwords_nodata.png
DELETED
Binary file
|
images/live.gif
ADDED
Binary file
|
images/logo.png
ADDED
Binary file
|
images/myheaderbg.png
DELETED
Binary file
|
images/new_ticket_title.jpg
ADDED
Binary file
|
images/newticket.png
ADDED
Binary file
|
images/online.png
ADDED
Binary file
|
images/openW.jpg
ADDED
Binary file
|
images/openW.png
ADDED
Binary file
|
images/output_ZD6GUg-1-2.gif
ADDED
Binary file
|
images/plugin-1.png
ADDED
Binary file
|
images/plugin-2.png
ADDED
Binary file
|
images/plugin-3.png
ADDED
Binary file
|
images/plugin-4.png
ADDED
Binary file
|
images/plugin-5.png
ADDED
Binary file
|
images/plugin-6.png
ADDED
Binary file
|
images/recent_nodata.png
DELETED
Binary file
|
images/se_nodata.png
DELETED
Binary file
|
images/searchengin.png
ADDED
Binary file
|
images/searchengins.png
ADDED
Binary file
|
images/settings.jpg
ADDED
Binary file
|
images/stats.png
ADDED
Binary file
|
images/stats2.png
ADDED
Binary file
|
images/stats2.psd
ADDED
Binary file
|
images/stats3.png
ADDED
Binary file
|
images/topref_nodata.png
DELETED
Binary file
|
images/up.png
ADDED
Binary file
|
images/upgrade.png
DELETED
Binary file
|
images/visitors.png
ADDED
Binary file
|
images/visits.png
ADDED
Binary file
|
images/vtrts.png
CHANGED
Binary file
|
images/vtrts_ads.gif
DELETED
Binary file
|
images/wordpress-plugins.png
ADDED
Binary file
|
init.php
CHANGED
@@ -1,15 +1,24 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
define('AHC_DS', DIRECTORY_SEPARATOR);
|
4 |
-
define('AHC_PLUGIN_SUPDIRE_FILE', dirname(__FILE__).'WP_Stats_Plus.php');
|
5 |
|
6 |
-
require_once("settings.php");
|
7 |
require_once("WPHitsCounter.php");
|
8 |
|
9 |
-
register_activation_hook(
|
10 |
-
register_deactivation_hook(
|
|
|
|
|
11 |
|
12 |
-
class
|
13 |
|
14 |
static $plugin_options = array();
|
15 |
static $lang = NULL;
|
@@ -18,32 +27,53 @@ class Globals{
|
|
18 |
static $page_title = NULL;
|
19 |
}
|
20 |
|
21 |
-
|
22 |
-
|
23 |
|
24 |
|
|
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
if (isset($_GET['page'])) $admincore = $_GET['page'];
|
30 |
-
if( is_admin() && $admincore == '
|
31 |
{
|
32 |
-
add_action('admin_enqueue_scripts', '
|
33 |
}
|
34 |
|
35 |
-
//add_action('admin_bar_menu', 'vtrts_add_items', 90);
|
36 |
-
//$plugin = plugin_basename( __FILE__ );
|
37 |
-
//add_filter( "plugin_action_links_$plugin", 'vtrtsp_plugin_add_settings_link' );
|
38 |
-
|
39 |
|
|
|
|
|
40 |
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
// creating Ajax call for WordPress
|
45 |
-
add_action( 'wp_ajax_nopriv_ahc_HideMessageAjaxFunction', 'ahc_HideMessageAjaxFunction' );
|
46 |
-
add_action( 'wp_ajax_ahc_HideMessageAjaxFunction', 'ahc_HideMessageAjaxFunction' );
|
47 |
-
|
48 |
|
49 |
-
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
+
define('AHC_RECENT_VISITORS_LIMIT', 20);
|
3 |
+
define('AHCFREE_RECENT_KEYWORDS_LIMIT', 20);
|
4 |
+
|
5 |
+
define('AHCFREE_TOP_REFERING_SITES_LIMIT', 20); // used in ahcfree_get_top_refering_sites
|
6 |
+
define('AHCFREE_TOP_COUNTRIES_LIMIT', 20); // used in ahcfree_get_top_countries
|
7 |
+
|
8 |
+
define('AHCFREE_TRAFFIC_BY_TITLE_LIMIT', 20);
|
9 |
+
define('IS_DEMO', true);
|
10 |
+
define('AHCFREE_DS', DIRECTORY_SEPARATOR);
|
11 |
+
define('AHCFREE_PLUGIN_SUPDIRE_FILE', dirname(__FILE__).'visitors-traffic-real-time-statistics.php');
|
12 |
|
|
|
|
|
13 |
|
|
|
14 |
require_once("WPHitsCounter.php");
|
15 |
|
16 |
+
register_activation_hook(AHCFREE_PLUGIN_MAIN_FILE, 'ahcfree_set_default_options');
|
17 |
+
register_deactivation_hook(AHCFREE_PLUGIN_MAIN_FILE, 'ahcfree_unset_default_options');
|
18 |
+
|
19 |
+
|
20 |
|
21 |
+
class Globalsahcfree{
|
22 |
|
23 |
static $plugin_options = array();
|
24 |
static $lang = NULL;
|
27 |
static $page_title = NULL;
|
28 |
}
|
29 |
|
30 |
+
Globalsahcfree::$plugin_options = get_option('ahcfree_wp_hits_counter_options');
|
31 |
+
Globalsahcfree::$lang = 'en';
|
32 |
|
33 |
|
34 |
+
$ahcfree_get_save_settings = ahcfree_get_save_settings();
|
35 |
|
36 |
+
if($ahcfree_get_save_settings == false or empty($ahcfree_get_save_settings))
|
37 |
+
{
|
38 |
+
ahcfree_add_settings();
|
39 |
+
}
|
40 |
+
|
41 |
+
if(isset($ahcfree_get_save_settings[0]))
|
42 |
+
{
|
43 |
+
$hits_days = $ahcfree_get_save_settings[0]->set_hits_days;
|
44 |
+
$ajax_check = ($ahcfree_get_save_settings[0]->set_ajax_check * 1000);
|
45 |
+
$set_ips = $ahcfree_get_save_settings[0]->set_ips;
|
46 |
+
$set_google_map = $ahcfree_get_save_settings[0]->set_google_map;
|
47 |
+
}else{
|
48 |
+
$hits_days = 14;
|
49 |
+
$ajax_check = 15;
|
50 |
+
$set_ips = '';
|
51 |
+
$set_google_map = 'today_visitors';
|
52 |
+
}
|
53 |
+
|
54 |
+
define('AHC_VISITORS_VISITS_LIMIT', $hits_days );
|
55 |
+
define('AHCFREE_AJAX_CHECK', $ajax_check);
|
56 |
+
define('AHCFREE_EXCLUDE_IPS', $set_ips);
|
57 |
+
|
58 |
+
|
59 |
+
|
60 |
+
$admincore = '';
|
61 |
if (isset($_GET['page'])) $admincore = $_GET['page'];
|
62 |
+
if( is_admin() && $admincore == 'ahc_hits_counter_menu_free')
|
63 |
{
|
64 |
+
add_action('admin_enqueue_scripts', 'ahcfree_include_scripts');
|
65 |
}
|
66 |
|
|
|
|
|
|
|
|
|
67 |
|
68 |
+
add_action('admin_menu', 'ahcfree_create_admin_menu_link');
|
69 |
+
add_action('wp_ajax_ahcfree_get_hits_by_custom_duration','ahcfree_get_hits_by_custom_duration_callback');
|
70 |
|
71 |
+
define('AHCFREE_SERVER_CURRENT_TIMEZONE','+00:00');
|
72 |
+
$stats_current_timezone = get_option('ahcfree_custom_timezone');
|
73 |
+
$stats_current_timezone = !empty($stats_current_timezone) ? $stats_current_timezone : ahcfree_GetWPTimezoneString();
|
|
|
|
|
|
|
|
|
74 |
|
75 |
+
/*
|
76 |
+
if($stats_current_timezone !='')
|
77 |
+
date_default_timezone_set($stats_current_timezone);
|
78 |
+
*/
|
79 |
+
?>
|
js/ahc_jqscripts.js
ADDED
@@ -0,0 +1,358 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var colors = ['#DB6946', '#C14543', '#445060', '#395953', '#6C8C80', '#829AB5', '#BF807A', '#BF0000', '#006BB7', '#EC732C', '#BF3D27', '#A6375F',
|
2 |
+
'#8C6D46', '#326149', '#802B35', '#8A3842', '#366D73', '#4D6173', '#4A4659', '#C9D65B', '#F45552', '#F3CC5E', '#F29B88', '#D96941',
|
3 |
+
'#484F73', '#C9AB81', '#F5655C', '#F0C480'];
|
4 |
+
|
5 |
+
|
6 |
+
var $ = jQuery;
|
7 |
+
var save_method; //for save method string
|
8 |
+
var host=window.location.hostname;
|
9 |
+
var fullpath=window.location.pathname;
|
10 |
+
var fullparam=window.location.search.split('&');
|
11 |
+
|
12 |
+
var firstparam=fullparam[0];
|
13 |
+
var secoundparam=fullparam[1];
|
14 |
+
|
15 |
+
|
16 |
+
function checkTime(i) {
|
17 |
+
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
|
18 |
+
return i;
|
19 |
+
}
|
20 |
+
|
21 |
+
|
22 |
+
jQuery(document).ready(function () {
|
23 |
+
|
24 |
+
|
25 |
+
setInterval(function(){
|
26 |
+
|
27 |
+
var now = new Date();
|
28 |
+
var year = now.getFullYear();
|
29 |
+
var month = now.getMonth()+1;
|
30 |
+
var day = now.getDate();
|
31 |
+
var hour = now.getHours();
|
32 |
+
var minute = now.getMinutes();
|
33 |
+
var second = now.getSeconds();
|
34 |
+
if(month.toString().length == 1) {
|
35 |
+
month = '0'+month;
|
36 |
+
}
|
37 |
+
if(day.toString().length == 1) {
|
38 |
+
day = '0'+day;
|
39 |
+
}
|
40 |
+
if(hour.toString().length == 1) {
|
41 |
+
hour = '0'+hour;
|
42 |
+
}
|
43 |
+
if(minute.toString().length == 1) {
|
44 |
+
minute = '0'+minute;
|
45 |
+
}
|
46 |
+
if(second.toString().length == 1) {
|
47 |
+
second = '0'+second;
|
48 |
+
}
|
49 |
+
var dateTime = year+'/'+month+'/'+day+' '+hour+':'+minute+':'+second;
|
50 |
+
|
51 |
+
jQuery('#ahcfree_currenttime').html(dateTime); }, 500);
|
52 |
+
|
53 |
+
|
54 |
+
|
55 |
+
jQuery(document).on('click', '.SwalBtn1', function() {
|
56 |
+
swal.clickConfirm();
|
57 |
+
});
|
58 |
+
jQuery(document).on('click', '.SwalBtn2', function() {
|
59 |
+
window.open(
|
60 |
+
"https://www.wp-buy.com/product/visitors-traffic-real-time-statistics-pro/?popup=1",
|
61 |
+
'_blank'
|
62 |
+
);
|
63 |
+
|
64 |
+
swal.clickConfirm();
|
65 |
+
});
|
66 |
+
jQuery(document).on('click', '.SwalBtn3', function() {
|
67 |
+
localStorage.setItem("ahcfreemsg", "1");
|
68 |
+
swal.clickConfirm();
|
69 |
+
});
|
70 |
+
|
71 |
+
if(localStorage && (firstparam=="?page=ahc_hits_counter_menu_free"))
|
72 |
+
{
|
73 |
+
|
74 |
+
|
75 |
+
if (!localStorage.getItem("ahcfreemsg")==true)
|
76 |
+
{
|
77 |
+
|
78 |
+
swal({
|
79 |
+
title: '',
|
80 |
+
text: '',
|
81 |
+
imageUrl: 'https://www.wp-buy.com/wp-content/uploads/2018/10/output_ZD6GUg-1-2.gif',
|
82 |
+
imageWidth: 'auto',
|
83 |
+
imageHeight: 'auto',
|
84 |
+
imageAlt: 'Need more statistics, GEO locations & online counter?',
|
85 |
+
animation: true,
|
86 |
+
customClass: 'swal-noscroll',
|
87 |
+
allowEscapeKey:true,
|
88 |
+
showCancelButton: false,
|
89 |
+
showConfirmButton: false,
|
90 |
+
html: '<center><button type="button" role="button" class="confirm btn btn-lg btn-success SwalBtn2">' + 'Upgrade to pro' + '</button> ' +
|
91 |
+
'<button type="button" role="button" class="cancel btn btn-info SwalBtn1">' + 'Close' + '</button> '+
|
92 |
+
'<button type="button" role="button" class="confirm btn btn-warning SwalBtn3">' + "Dismiss" + '</button></center>'
|
93 |
+
});
|
94 |
+
|
95 |
+
|
96 |
+
|
97 |
+
|
98 |
+
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
|
104 |
+
|
105 |
+
|
106 |
+
});
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
|
111 |
+
//------------------------------------------------------------------------------
|
112 |
+
function convertToNumeric(data){
|
113 |
+
if(data instanceof Array){
|
114 |
+
for(var index in data){
|
115 |
+
data[index] = Number(data[index]);
|
116 |
+
}
|
117 |
+
} else{
|
118 |
+
data = Number(data);
|
119 |
+
}
|
120 |
+
return data;
|
121 |
+
}
|
122 |
+
//------------------------------------------------------------------------------
|
123 |
+
function getRandomElementFromArray(array){
|
124 |
+
var ranIndex = Math.floor(Math.random() * array.length);
|
125 |
+
return array[ranIndex];
|
126 |
+
}
|
127 |
+
//------------------------------------------------------------------------------
|
128 |
+
function drawVisitsLineChart(visitsData){
|
129 |
+
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
|
130 |
+
|
131 |
+
var barChartData = {
|
132 |
+
labels : visitsData.data.dates,
|
133 |
+
datasets : [
|
134 |
+
{
|
135 |
+
label: "Visitors",
|
136 |
+
barShowStroke: false,
|
137 |
+
fillColor : "rgba(75,178,1970,.5)",
|
138 |
+
strokeColor : "rgba(75,178,1970,.5)",
|
139 |
+
highlightFill: "rgba(220,220,220,0.75)",
|
140 |
+
highlightStroke: "rgba(220,220,220,1)",
|
141 |
+
data : visitsData.data.visitors
|
142 |
+
},
|
143 |
+
{
|
144 |
+
label: "Visits",
|
145 |
+
barShowStroke: false,
|
146 |
+
fillColor : "rgba(234,162,40,0.5)",
|
147 |
+
strokeColor : "rgba(234,162,40,0.5)",
|
148 |
+
highlightFill : "rgba(151,187,205,0.75)",
|
149 |
+
highlightStroke : "rgba(151,187,205,1)",
|
150 |
+
data : visitsData.data.visits
|
151 |
+
}
|
152 |
+
]
|
153 |
+
|
154 |
+
}
|
155 |
+
var ctx = document.getElementById("visitorsVisitsChart").getContext("2d");
|
156 |
+
window.myBar = new Chart(ctx).Bar(barChartData, {
|
157 |
+
responsive : true
|
158 |
+
});
|
159 |
+
}
|
160 |
+
//------------------------------------------------------------------------------
|
161 |
+
|
162 |
+
|
163 |
+
function drawBrowsersBieChart(browsersData){
|
164 |
+
|
165 |
+
|
166 |
+
if(browsersData.length > 0)
|
167 |
+
{
|
168 |
+
|
169 |
+
var brsBieChartData = [];
|
170 |
+
var brsBieChartDataLables = [];
|
171 |
+
brsBieChartDataLables[0] = '';
|
172 |
+
brsBieChartDataLables[1] = '';
|
173 |
+
brsBieChartDataLables[2] = '';
|
174 |
+
brsBieChartDataLables[3] = '';
|
175 |
+
brsBieChartDataLables[4] = '';
|
176 |
+
|
177 |
+
for(var i = 0; i < browsersData.length; i++){
|
178 |
+
var color = getRandomElementFromArray(colors);
|
179 |
+
var value = Number(browsersData[i].hits);
|
180 |
+
brsBieChartData[i] = value;
|
181 |
+
brsBieChartDataLables[i] = browsersData[i].bsr_name;
|
182 |
+
|
183 |
+
|
184 |
+
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
|
189 |
+
|
190 |
+
|
191 |
+
|
192 |
+
var config = {
|
193 |
+
type: 'pie',
|
194 |
+
data: {
|
195 |
+
datasets: [{
|
196 |
+
data: [
|
197 |
+
brsBieChartData[0],
|
198 |
+
brsBieChartData[1],
|
199 |
+
brsBieChartData[2],
|
200 |
+
brsBieChartData[3],
|
201 |
+
brsBieChartData[4]
|
202 |
+
|
203 |
+
],
|
204 |
+
backgroundColor: [
|
205 |
+
window.chartColors.red,
|
206 |
+
window.chartColors.orange,
|
207 |
+
window.chartColors.yellow,
|
208 |
+
window.chartColors.green,
|
209 |
+
window.chartColors.blue,
|
210 |
+
],
|
211 |
+
label: 'Browser'
|
212 |
+
}],
|
213 |
+
labels: [
|
214 |
+
|
215 |
+
brsBieChartDataLables[0],
|
216 |
+
brsBieChartDataLables[1],
|
217 |
+
brsBieChartDataLables[2],
|
218 |
+
brsBieChartDataLables[3],
|
219 |
+
brsBieChartDataLables[4],
|
220 |
+
|
221 |
+
|
222 |
+
]
|
223 |
+
},
|
224 |
+
options: {
|
225 |
+
responsive: true
|
226 |
+
}
|
227 |
+
};
|
228 |
+
|
229 |
+
window.onload = function() {
|
230 |
+
var ctx = document.getElementById('brsBiechartContainer').getContext('2d');
|
231 |
+
window.myPie = new Chart(ctx, config);
|
232 |
+
};
|
233 |
+
|
234 |
+
}else{
|
235 |
+
|
236 |
+
document.getElementById('brsBiechartContainer_msg').innerHTML = '<center>No data to display</center>';
|
237 |
+
}
|
238 |
+
|
239 |
+
|
240 |
+
|
241 |
+
}
|
242 |
+
|
243 |
+
|
244 |
+
//------------------------------------------------------------------------------
|
245 |
+
function drawSrhEngVstLineChart(srhEngVisitsData){
|
246 |
+
|
247 |
+
|
248 |
+
if(srhEngVisitsData.length > 0)
|
249 |
+
{
|
250 |
+
var srhBieChartData = [];
|
251 |
+
var srhBieChartDataLables = [];
|
252 |
+
srhBieChartDataLables[0] = '';
|
253 |
+
srhBieChartDataLables[1] = '';
|
254 |
+
srhBieChartDataLables[2] = '';
|
255 |
+
srhBieChartDataLables[3] = '';
|
256 |
+
srhBieChartDataLables[4] = '';
|
257 |
+
|
258 |
+
for(var i = 0; i < srhEngVisitsData.length; i++){
|
259 |
+
var color = getRandomElementFromArray(colors);
|
260 |
+
var value = Number(srhEngVisitsData[i].hits);
|
261 |
+
srhBieChartData[i] = value;
|
262 |
+
srhBieChartDataLables[i] = srhEngVisitsData[i].bsr_name;
|
263 |
+
|
264 |
+
|
265 |
+
}
|
266 |
+
|
267 |
+
|
268 |
+
|
269 |
+
|
270 |
+
|
271 |
+
|
272 |
+
var config = {
|
273 |
+
type: 'pie',
|
274 |
+
data: {
|
275 |
+
datasets: [{
|
276 |
+
data: [
|
277 |
+
srhBieChartData[0],
|
278 |
+
srhBieChartData[1],
|
279 |
+
srhBieChartData[2],
|
280 |
+
srhBieChartData[3],
|
281 |
+
srhBieChartData[4]
|
282 |
+
|
283 |
+
],
|
284 |
+
backgroundColor: [
|
285 |
+
window.chartColors.yellow,
|
286 |
+
window.chartColors.green,
|
287 |
+
window.chartColors.blue,
|
288 |
+
window.chartColors.red,
|
289 |
+
window.chartColors.orange,
|
290 |
+
|
291 |
+
],
|
292 |
+
label: 'Search Engine'
|
293 |
+
}],
|
294 |
+
labels: [
|
295 |
+
|
296 |
+
srhBieChartDataLables[0],
|
297 |
+
srhBieChartDataLables[1],
|
298 |
+
srhBieChartDataLables[2],
|
299 |
+
srhBieChartDataLables[3],
|
300 |
+
srhBieChartDataLables[4],
|
301 |
+
|
302 |
+
|
303 |
+
]
|
304 |
+
},
|
305 |
+
options: {
|
306 |
+
responsive: true
|
307 |
+
}
|
308 |
+
};
|
309 |
+
|
310 |
+
var ctx2 = document.getElementById('srhEngBieChartContainer').getContext('2d');
|
311 |
+
window.myPie = new Chart(ctx2, config);
|
312 |
+
window.myPie = new Chart(ctx2, config);
|
313 |
+
}else{
|
314 |
+
|
315 |
+
document.getElementById('srhEngBieChartContainer_msg').innerHTML = '<center>No data to display</center>';
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
|
320 |
+
function isEmpty(val){
|
321 |
+
return (val == null || val == 0 || val == '' || val == '0');
|
322 |
+
}
|
323 |
+
|
324 |
+
//------------------------------------------------------------------------------
|
325 |
+
function countVisits(arr){
|
326 |
+
var count = 0;
|
327 |
+
for(var i = 0; i < arr.length; i++){
|
328 |
+
count += Number(arr[i]);
|
329 |
+
}
|
330 |
+
return count;
|
331 |
+
}
|
332 |
+
//------------------------------------------------------------------------------
|
333 |
+
|
334 |
+
jQuery(document).ready(function () {
|
335 |
+
|
336 |
+
|
337 |
+
if(typeof browsersData !== 'undefined')
|
338 |
+
{
|
339 |
+
|
340 |
+
//------------------------------------------
|
341 |
+
//if(visitsData.success && typeof visitsData.data != 'undefined'){
|
342 |
+
var duration = jQuery('#hits-duration').val();
|
343 |
+
drawVisitsLineChart( mystart_date, myend_date, '1 day', visitors_data, visits_data, duration );
|
344 |
+
//}
|
345 |
+
//------------------------------------------
|
346 |
+
if (browsersData.success && typeof browsersData.data != 'undefined' && typeof drawBrowsersBieChart === "function") {
|
347 |
+
drawBrowsersBieChart(browsersData.data);
|
348 |
+
}
|
349 |
+
//------------------------------------------
|
350 |
+
if (srhEngVisitsData.success && typeof srhEngVisitsData.data != 'undefined' && typeof drawSrhEngVstLineChart === "function") {
|
351 |
+
|
352 |
+
drawSrhEngVstLineChart(srhEngVisitsData.data);
|
353 |
+
}
|
354 |
+
//------------------------------------------
|
355 |
+
|
356 |
+
//------------------------------------------
|
357 |
+
}
|
358 |
+
});
|
js/front.js
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var pageid = ahcfree_ajax_front.page_id;
|
2 |
+
var page_id = (pageid.length > 0) ? pageid : '';
|
3 |
+
var pagetitle = ahcfree_ajax_front.page_title;
|
4 |
+
var page_title = (pagetitle.length > 0) ? pagetitle : '';
|
5 |
+
var posttype = ahcfree_ajax_front.post_type;
|
6 |
+
var post_type = (posttype.length > 0) ? posttype : '';
|
7 |
+
var referer = document.referrer;
|
8 |
+
var useragent = window.navigator.userAgent;
|
9 |
+
var servername = location.hostname;
|
10 |
+
var hostname = location.host;
|
11 |
+
var request_uri = location.pathname.substring(1);
|
12 |
+
|
13 |
+
var xhttp = new XMLHttpRequest();
|
14 |
+
|
15 |
+
xhttp.open("POST", ahcfree_ajax_front.ajax_url, true);
|
16 |
+
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
17 |
+
xhttp.send("action=ahcfree_track_visitor&page_id="+ page_id +"&page_title="+ page_title + "&post_type="+ post_type + "&referer="+ referer +"&useragent="+ useragent +"&servername="+ servername +"&hostname="+ hostname +"&request_uri="+request_uri);
|
18 |
+
/*
|
19 |
+
|
20 |
+
jQuery(document).ready(function ()
|
21 |
+
{
|
22 |
+
var pageid = ahcfree_ajax_front.page_id;
|
23 |
+
var page_id = (pageid.length > 0) ? pageid : '';
|
24 |
+
var pagetitle = ahcfree_ajax_front.page_title;
|
25 |
+
var page_title = (pagetitle.length > 0) ? pagetitle : '';
|
26 |
+
var posttype = ahcfree_ajax_front.post_type;
|
27 |
+
var post_type = (posttype.length > 0) ? posttype : '';
|
28 |
+
var referer = document.referrer;
|
29 |
+
var useragent = window.navigator.userAgent;
|
30 |
+
var servername = location.hostname;
|
31 |
+
var hostname = location.host;
|
32 |
+
var request_uri = location.pathname.substring(1);
|
33 |
+
|
34 |
+
jQuery.ajax({
|
35 |
+
type: 'POST',
|
36 |
+
url : ahcfree_ajax_front.ajax_url,
|
37 |
+
data: {
|
38 |
+
'action': 'ahcfree_track_visitor',
|
39 |
+
'page_id': page_id,
|
40 |
+
'page_title': page_title,
|
41 |
+
'post_type': post_type,
|
42 |
+
'referer': referer,
|
43 |
+
'useragent':useragent,
|
44 |
+
'servername':servername,
|
45 |
+
'hostname':hostname,
|
46 |
+
'request_uri':request_uri
|
47 |
+
},
|
48 |
+
success: function(data){
|
49 |
+
console.log(data);
|
50 |
+
},
|
51 |
+
error: function(data)
|
52 |
+
{
|
53 |
+
console.log(data);
|
54 |
+
}
|
55 |
+
});
|
56 |
+
});
|
57 |
+
*/
|
58 |
+
|
59 |
+
|
js/jqplot.canvasAxisLabelRenderer.min.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com
|
2 |
+
jsDate | (c) 2010-2013 Chris Leonello
|
3 |
+
*/(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this.axis!="x2axis"){this.angle=-90}var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisLabelRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisLabelRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisLabelRenderer.prototype.draw=function(c,f){if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css({position:"absolute"});this._elem.addClass("jqplot-"+this.axis+"-label");e=null;return this._elem};a.jqplot.CanvasAxisLabelRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery);
|
js/jqplot.canvasAxisTickRenderer.min.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com
|
2 |
+
jsDate | (c) 2010-2013 Chris Leonello
|
3 |
+
*/(function(a){a.jqplot.CanvasAxisTickRenderer=function(b){this.mark="outside";this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.angle=0;this.markSize=4;this.show=true;this.showLabel=true;this.labelPosition="auto";this.label="";this.value=null;this._styles={};this.formatter=a.jqplot.DefaultTickFormatter;this.formatString="";this.prefix="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="10pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisTickRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisTickRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getTop=function(b){if(this._elem){return this._elem.position().top}else{return null}};a.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisTickRenderer.prototype.setTick=function(b,d,c){this.value=b;if(c){this.isMinorTick=true}return this};a.jqplot.CanvasAxisTickRenderer.prototype.draw=function(c,f){if(!this.label){this.label=this.prefix+this.formatter(this.formatString,this.value)}if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.textAlign="left";e.style.position="absolute";e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css(this._styles);this._elem.addClass("jqplot-"+this.axis+"-tick");e=null;return this._elem};a.jqplot.CanvasAxisTickRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery);
|
js/jqplot.canvasTextRenderer.min.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com
|
2 |
+
jsDate | (c) 2010-2013 Chris Leonello
|
3 |
+
*/(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function(b){a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.normalizeFontSize=function(b){b=String(b);var c=parseFloat(b);if(b.indexOf("px")>-1){return c/this.pt2px}else{if(b.indexOf("pt")>-1){return c}else{if(b.indexOf("em")>-1){return c*12}else{if(b.indexOf("%")>-1){return c*12/100}else{return c/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.CanvasTextRenderer.prototype.measure=function(d,g){var f=0;var b=g.length;for(var e=0;e<b;e++){var h=this.letter(g.charAt(e));if(h){f+=h.width*this.normalizedFontSize/25*this.fontStretch}}return f};a.jqplot.CanvasTextRenderer.prototype.draw=function(s,n){var r=0;var o=this.height*0.72;var p=0;var l=n.length;var k=this.normalizedFontSize/25;s.save();var h,f;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){h=0;f=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){h=Math.sin(this.angle)*this.height;f=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){h=-Math.cos(this.angle)*this.width;f=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){h=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;f=-Math.cos(this.angle)*this.height}}}}s.strokeStyle=this.fillStyle;s.fillStyle=this.fillStyle;s.translate(h,f);s.rotate(this.angle);s.lineCap="round";var t=(this.normalizedFontSize>30)?2:2+(30-this.normalizedFontSize)/20;s.lineWidth=t*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g<l;g++){var m=this.letter(n.charAt(g));if(!m){continue}s.beginPath();var e=1;var b=0;for(var d=0;d<m.points.length;d++){var q=m.points[d];if(q[0]==-1&&q[1]==-1){e=1;continue}if(e){s.moveTo(r+q[0]*k*this.fontStretch,o-q[1]*k);e=false}else{s.lineTo(r+q[0]*k*this.fontStretch,o-q[1]*k)}}s.stroke();r+=m.width*k*this.fontStretch}s.restore();return p};a.jqplot.CanvasTextRenderer.prototype.letters={" ":{width:16,points:[]},"!":{width:10,points:[[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},'"':{width:16,points:[[4,21],[4,14],[-1,-1],[12,21],[12,14]]},"#":{width:21,points:[[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]]},"$":{width:20,points:[[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},"%":{width:24,points:[[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]]},"&":{width:26,points:[[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]]},"'":{width:10,points:[[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]]},"(":{width:14,points:[[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]]},")":{width:14,points:[[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]]},"*":{width:16,points:[[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]]},"+":{width:26,points:[[13,18],[13,0],[-1,-1],[4,9],[22,9]]},",":{width:10,points:[[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"-":{width:18,points:[[6,9],[12,9]]},".":{width:10,points:[[5,2],[4,1],[5,0],[6,1],[5,2]]},"/":{width:22,points:[[20,25],[2,-7]]},"0":{width:20,points:[[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]]},"1":{width:20,points:[[6,17],[8,18],[11,21],[11,0]]},"2":{width:20,points:[[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]]},"3":{width:20,points:[[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"4":{width:20,points:[[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]]},"5":{width:20,points:[[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"6":{width:20,points:[[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]]},"7":{width:20,points:[[17,21],[7,0],[-1,-1],[3,21],[17,21]]},"8":{width:20,points:[[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]]},"9":{width:20,points:[[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]]},":":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},";":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"<":{width:24,points:[[20,18],[4,9],[20,0]]},"=":{width:26,points:[[4,12],[22,12],[-1,-1],[4,6],[22,6]]},">":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){d=Math.sin(this.angle)*this.height;b=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){d=-Math.cos(this.angle)*this.width;b=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){d=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;b=-Math.cos(this.angle)*this.height}}}}e.strokeStyle=this.fillStyle;e.fillStyle=this.fillStyle;var f=this.fontSize+" "+this.fontFamily;e.font=f;e.translate(d,b);e.rotate(this.angle);e.fillText(g,c,h);e.restore()}})(jQuery);
|
js/jqplot.dateAxisRenderer.min.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com
|
2 |
+
jsDate | (c) 2010-2013 Chris Leonello
|
3 |
+
*/(function(h){h.jqplot.DateAxisRenderer=function(){h.jqplot.LinearAxisRenderer.call(this);this.date=new h.jsDate()};var c=1000;var e=60*c;var f=60*e;var l=24*f;var b=7*l;var j=30.4368499*l;var k=365.242199*l;var g=[31,28,31,30,31,30,31,30,31,30,31,30];var i=["%M:%S.%#N","%M:%S.%#N","%M:%S.%#N","%M:%S","%M:%S","%M:%S","%M:%S","%H:%M:%S","%H:%M:%S","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%a %H:%M","%a %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%v","%v","%v","%v","%v","%v","%v"];var m=[0.1*c,0.2*c,0.5*c,c,2*c,5*c,10*c,15*c,30*c,e,2*e,5*e,10*e,15*e,30*e,f,2*f,4*f,6*f,8*f,12*f,l,2*l,3*l,4*l,5*l,b,2*b];var d=[];function a(p,s,t){var o=Number.MAX_VALUE;var u,r,v;for(var q=0,n=m.length;q<n;q++){u=Math.abs(t-m[q]);if(u<o){o=u;r=m[q];v=i[q]}}return[r,v]}h.jqplot.DateAxisRenderer.prototype=new h.jqplot.LinearAxisRenderer();h.jqplot.DateAxisRenderer.prototype.constructor=h.jqplot.DateAxisRenderer;h.jqplot.DateTickFormatter=function(n,o){if(!n){n="%Y/%m/%d"}return h.jsDate.strftime(o,n)};h.jqplot.DateAxisRenderer.prototype.init=function(E){this.tickOptions.formatter=h.jqplot.DateTickFormatter;this.tickInset=0;this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.daTickInterval=null;this._daTickInterval=null;h.extend(true,this,E);var C=this._dataBounds,u,x,D,y,A,z,o;for(var t=0;t<this._series.length;t++){u={intervals:[],frequencies:{},sortedIntervals:[],min:null,max:null,mean:null};x=0;D=this._series[t];y=D.data;A=D._plotData;z=D._stackData;o=0;for(var r=0;r<y.length;r++){if(this.name=="xaxis"||this.name=="x2axis"){y[r][0]=new h.jsDate(y[r][0]).getTime();A[r][0]=new h.jsDate(y[r][0]).getTime();z[r][0]=new h.jsDate(y[r][0]).getTime();if((y[r][0]!=null&&y[r][0]<C.min)||C.min==null){C.min=y[r][0]}if((y[r][0]!=null&&y[r][0]>C.max)||C.max==null){C.max=y[r][0]}if(r>0){o=Math.abs(y[r][0]-y[r-1][0]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}x+=o}else{y[r][1]=new h.jsDate(y[r][1]).getTime();A[r][1]=new h.jsDate(y[r][1]).getTime();z[r][1]=new h.jsDate(y[r][1]).getTime();if((y[r][1]!=null&&y[r][1]<C.min)||C.min==null){C.min=y[r][1]}if((y[r][1]!=null&&y[r][1]>C.max)||C.max==null){C.max=y[r][1]}if(r>0){o=Math.abs(y[r][1]-y[r-1][1]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}}x+=o}if(D.renderer.bands){if(D.renderer.bands.hiData.length){var w=D.renderer.bands.hiData;for(var r=0,q=w.length;r<q;r++){if(this.name==="xaxis"||this.name==="x2axis"){w[r][0]=new h.jsDate(w[r][0]).getTime();if((w[r][0]!=null&&w[r][0]>C.max)||C.max==null){C.max=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]>C.max)||C.max==null){C.max=w[r][1]}}}}if(D.renderer.bands.lowData.length){var w=D.renderer.bands.lowData;for(var r=0,q=w.length;r<q;r++){if(this.name==="xaxis"||this.name==="x2axis"){w[r][0]=new h.jsDate(w[r][0]).getTime();if((w[r][0]!=null&&w[r][0]<C.min)||C.min==null){C.min=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]<C.min)||C.min==null){C.min=w[r][1]}}}}}var B=0,v=0;for(var p in u.frequencies){u.sortedIntervals.push({interval:p,frequency:u.frequencies[p]})}u.sortedIntervals.sort(function(s,n){return n.frequency-s.frequency});u.min=h.jqplot.arrayMin(u.intervals);u.max=h.jqplot.arrayMax(u.intervals);u.mean=x/y.length;this._intervalStats.push(u);u=x=D=y=A=z=null}C=null};h.jqplot.DateAxisRenderer.prototype.reset=function(){this.min=this._options.min;this.max=this._options.max;this.tickInterval=this._options.tickInterval;this.numberTicks=this._options.numberTicks;this._autoFormatString="";if(this._overrideFormatString&&this.tickOptions&&this.tickOptions.formatString){this.tickOptions.formatString=""}this.daTickInterval=this._daTickInterval};h.jqplot.DateAxisRenderer.prototype.createTicks=function(p){var X=this._ticks;var L=this.ticks;var F=this.name;var H=this._dataBounds;var M=this._intervalStats;var n=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var w;var ae,J;var y,x;var ad,aa;var s=30;var O=1;var U=null;if(this.tickInterval!=null){if(Number(this.tickInterval)){U=[Number(this.tickInterval),"seconds"]}else{if(typeof this.tickInterval=="string"){var ac=this.tickInterval.split(" ");if(ac.length==1){U=[1,ac[0]]}else{if(ac.length==2){U=[ac[0],ac[1]]}}}}}var v=this.tickInterval;ae=new h.jsDate((this.min!=null)?this.min:H.min).getTime();J=new h.jsDate((this.max!=null)?this.max:H.max).getTime();var A=p.plugins.cursor;if(A&&A._zoom&&A._zoom.zooming){this.min=null;this.max=null}var B=J-ae;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(L.length){for(aa=0;aa<L.length;aa++){var P=L[aa];var Y=new this.tickRenderer(this.tickOptions);if(P.constructor==Array){Y.value=new h.jsDate(P[0]).getTime();Y.label=P[1];if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(Y.value,this.name);this._ticks.push(Y)}else{Y.value=new h.jsDate(P).getTime();if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(Y.value,this.name);this._ticks.push(Y)}}this.numberTicks=L.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.daTickInterval=[(this.max-this.min)/(this.numberTicks-1)/1000,"seconds"]}else{if(this.min==null&&this.max==null&&H.min==H.max){var E=h.extend(true,{},this.tickOptions,{name:this.name,value:null});var T=300000;this.min=H.min-T;this.max=H.max+T;this.numberTicks=3;for(var aa=this.min;aa<=this.max;aa+=T){E.value=aa;var Y=new this.tickRenderer(E);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}Y.showLabel=false;Y.showMark=false;this._ticks.push(Y)}if(this.showTicks){this._ticks[1].showLabel=true}if(this.showTickMarks){this._ticks[1].showTickMarks=true}}else{if(this.min==null&&this.max==null){var N=h.extend(true,{},this.tickOptions,{name:this.name,value:null});var ab,I;if(!this.tickInterval&&!this.numberTicks){var R=Math.max(n,s+1);var Z=115;if(this.tickRenderer===h.jqplot.CanvasAxisTickRenderer&&this.tickOptions.angle){Z=115-40*Math.abs(Math.sin(this.tickOptions.angle/180*Math.PI))}ab=Math.ceil((R-s)/Z+1);I=(J-ae)/(ab-1)}else{if(this.tickInterval){I=new h.jsDate(0).add(U[0],U[1]).getTime()}else{if(this.numberTicks){ab=this.numberTicks;I=(J-ae)/(ab-1)}}}if(I<=19*l){var Q=a(ae,J,I);var r=Q[0];this._autoFormatString=Q[1];ae=new h.jsDate(ae);ae=Math.floor((ae.getTime()-ae.getUtcOffset())/r)*r+ae.getUtcOffset();ab=Math.ceil((J-ae)/r)+1;this.min=ae;this.max=ae+(ab-1)*r;if(this.max<J){this.max+=r;ab+=1}this.tickInterval=r;this.numberTicks=ab;for(var aa=0;aa<ab;aa++){N.value=this.min+aa*r;Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=this.tickInterval}else{if(I<=9*j){this._autoFormatString="%v";var D=Math.round(I/j);if(D<1){D=1}else{if(D>6){D=6}}var V=new h.jsDate(ae).setDate(1).setHours(0,0,0,0);var q=new h.jsDate(J);var z=new h.jsDate(J).setDate(1).setHours(0,0,0,0);if(q.getTime()!==z.getTime()){z=z.add(1,"month")}var S=z.diff(V,"month");ab=Math.ceil(S/D)+1;this.min=V.getTime();this.max=V.clone().add((ab-1)*D,"month").getTime();this.numberTicks=ab;for(var aa=0;aa<ab;aa++){if(aa===0){N.value=V.getTime()}else{N.value=V.add(D,"month").getTime()}Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=D*j}else{this._autoFormatString="%v";var D=Math.round(I/k);if(D<1){D=1}var V=new h.jsDate(ae).setMonth(0,1).setHours(0,0,0,0);var z=new h.jsDate(J).add(1,"year").setMonth(0,1).setHours(0,0,0,0);var K=z.diff(V,"year");ab=Math.ceil(K/D)+1;this.min=V.getTime();this.max=V.clone().add((ab-1)*D,"year").getTime();this.numberTicks=ab;for(var aa=0;aa<ab;aa++){if(aa===0){N.value=V.getTime()}else{N.value=V.add(D,"year").getTime()}Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=D*k}}}else{if(F=="xaxis"||F=="x2axis"){n=this._plotDimensions.width}else{n=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}if(this.tickInterval!=null&&U!=null){this.daTickInterval=U}if(ae==J){var o=24*60*60*500;ae-=o;J+=o}B=J-ae;var G=2+parseInt(Math.max(0,n-100)/100,10);var W,C;W=(this.min!=null)?new h.jsDate(this.min).getTime():ae-B/2*(this.padMin-1);C=(this.max!=null)?new h.jsDate(this.max).getTime():J+B/2*(this.padMax-1);this.min=W;this.max=C;B=this.max-this.min;if(this.numberTicks==null){if(this.daTickInterval!=null){var u=new h.jsDate(this.max).diff(this.min,this.daTickInterval[1],true);this.numberTicks=Math.ceil(u/this.daTickInterval[0])+1;this.max=new h.jsDate(this.min).add((this.numberTicks-1)*this.daTickInterval[0],this.daTickInterval[1]).getTime()}else{if(n>200){this.numberTicks=parseInt(3+(n-200)/100,10)}else{this.numberTicks=2}}}O=B/(this.numberTicks-1)/1000;if(this.daTickInterval==null){this.daTickInterval=[O,"seconds"]}for(var aa=0;aa<this.numberTicks;aa++){var ae=new h.jsDate(this.min);ad=ae.add(aa*this.daTickInterval[0],this.daTickInterval[1]).getTime();var Y=new this.tickRenderer(this.tickOptions);if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(ad,this.name);this._ticks.push(Y)}}}}if(this.tickInset){this.min=this.min-this.tickInset*O;this.max=this.max+this.tickInset*O}if(this._daTickInterval==null){this._daTickInterval=this.daTickInterval}X=null}})(jQuery);
|
js/jqplot.enhancedLegendRenderer.min.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com
|
2 |
+
jsDate | (c) 2010-2013 Chris Leonello
|
3 |
+
*/(function(c){c.jqplot.EnhancedLegendRenderer=function(){c.jqplot.TableLegendRenderer.call(this)};c.jqplot.EnhancedLegendRenderer.prototype=new c.jqplot.TableLegendRenderer();c.jqplot.EnhancedLegendRenderer.prototype.constructor=c.jqplot.EnhancedLegendRenderer;c.jqplot.EnhancedLegendRenderer.prototype.init=function(d){this.numberRows=null;this.numberColumns=null;this.seriesToggle="normal";this.seriesToggleReplot=false;this.disableIEFading=true;c.extend(true,this,d);if(this.seriesToggle){c.jqplot.postDrawHooks.push(b)}};c.jqplot.EnhancedLegendRenderer.prototype.draw=function(m,y){var f=this;if(this.show){var r=this._series;var u;var w="position:absolute;";w+=(this.background)?"background:"+this.background+";":"";w+=(this.border)?"border:"+this.border+";":"";w+=(this.fontSize)?"font-size:"+this.fontSize+";":"";w+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";w+=(this.textColor)?"color:"+this.textColor+";":"";w+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";w+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";w+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";w+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=c('<table class="jqplot-table-legend" style="'+w+'"></table>');if(this.seriesToggle){this._elem.css("z-index","3")}var C=false,q=false,d,o;if(this.numberRows){d=this.numberRows;if(!this.numberColumns){o=Math.ceil(r.length/d)}else{o=this.numberColumns}}else{if(this.numberColumns){o=this.numberColumns;d=Math.ceil(r.length/this.numberColumns)}else{d=r.length;o=1}}var B,z,e,l,k,n,p,t,h,g;var v=0;for(B=r.length-1;B>=0;B--){if(o==1&&r[B]._stack||r[B].renderer.constructor==c.jqplot.BezierCurveRenderer){q=true}}for(B=0;B<d;B++){e=c(document.createElement("tr"));e.addClass("jqplot-table-legend");if(q){e.prependTo(this._elem)}else{e.appendTo(this._elem)}for(z=0;z<o;z++){if(v<r.length&&(r[v].show||r[v].showLabel)){u=r[v];n=this.labels[v]||u.label.toString();if(n){var x=u.color;if(!q){if(B>0){C=true}else{C=false}}else{if(B==d-1){C=false}else{C=true}}p=(C)?this.rowSpacing:"0";l=c(document.createElement("td"));l.addClass("jqplot-table-legend jqplot-table-legend-swatch");l.css({textAlign:"center",paddingTop:p});h=c(document.createElement("div"));h.addClass("jqplot-table-legend-swatch-outline");g=c(document.createElement("div"));g.addClass("jqplot-table-legend-swatch");g.css({backgroundColor:x,borderColor:x});l.append(h.append(g));k=c(document.createElement("td"));k.addClass("jqplot-table-legend jqplot-table-legend-label");k.css("paddingTop",p);if(this.escapeHtml){k.text(n)}else{k.html(n)}if(q){if(this.showLabels){k.prependTo(e)}if(this.showSwatches){l.prependTo(e)}}else{if(this.showSwatches){l.appendTo(e)}if(this.showLabels){k.appendTo(e)}}if(this.seriesToggle){var A;if(typeof(this.seriesToggle)==="string"||typeof(this.seriesToggle)==="number"){if(!c.jqplot.use_excanvas||!this.disableIEFading){A=this.seriesToggle}}if(this.showSwatches){l.bind("click",{series:u,speed:A,plot:y,replot:this.seriesToggleReplot},a);l.addClass("jqplot-seriesToggle")}if(this.showLabels){k.bind("click",{series:u,speed:A,plot:y,replot:this.seriesToggleReplot},a);k.addClass("jqplot-seriesToggle")}if(!u.show&&u.showLabel){l.addClass("jqplot-series-hidden");k.addClass("jqplot-series-hidden")}}C=true}}v++}l=k=h=g=null}}return this._elem};var a=function(j){var i=j.data,m=i.series,k=i.replot,h=i.plot,f=i.speed,l=m.index,g=false;if(m.canvas._elem.is(":hidden")||!m.show){g=true}var e=function(){if(k){var n={};if(c.isPlainObject(k)){c.extend(true,n,k)}h.replot(n);if(g&&f){var d=h.series[l];if(d.shadowCanvas._elem){d.shadowCanvas._elem.hide().fadeIn(f)}d.canvas._elem.hide().fadeIn(f);d.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+d.index).hide().fadeIn(f)}}else{var d=h.series[l];if(d.canvas._elem.is(":hidden")||!d.show){if(typeof h.options.legend.showSwatches==="undefined"||h.options.legend.showSwatches===true){h.legend._elem.find("td").eq(l*2).addClass("jqplot-series-hidden")}if(typeof h.options.legend.showLabels==="undefined"||h.options.legend.showLabels===true){h.legend._elem.find("td").eq((l*2)+1).addClass("jqplot-series-hidden")}}else{if(typeof h.options.legend.showSwatches==="undefined"||h.options.legend.showSwatches===true){h.legend._elem.find("td").eq(l*2).removeClass("jqplot-series-hidden")}if(typeof h.options.legend.showLabels==="undefined"||h.options.legend.showLabels===true){h.legend._elem.find("td").eq((l*2)+1).removeClass("jqplot-series-hidden")}}}};m.toggleDisplay(j,e)};var b=function(){if(this.legend.renderer.constructor==c.jqplot.EnhancedLegendRenderer&&this.legend.seriesToggle){var d=this.legend._elem.detach();this.eventCanvas._elem.after(d)}}})(jQuery);
|
js/jqplot.highlighter.min.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com
|
2 |
+
jsDate | (c) 2010-2013 Chris Leonello
|
3 |
+
*/(function(d){d.jqplot.eventListenerHooks.push(["jqplotMouseMove",f]);d.jqplot.Highlighter=function(h){this.show=d.jqplot.config.enablePlugins;this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.tooltipContentEditor=null;this.useAxesFormatters=true;this.tooltipFormatString="%.5P";this.formatString=null;this.yvalues=1;this.bringSeriesToFront=false;this._tooltipElem;this.isHighlighting=false;this.currentNeighbor=null;d.extend(true,this,h)};var b=["nw","n","ne","e","se","s","sw","w"];var e={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var c=["se","s","sw","w","nw","n","ne","e"];d.jqplot.Highlighter.init=function(k,j,i){var h=i||{};this.plugins.highlighter=new d.jqplot.Highlighter(h.highlighter)};d.jqplot.Highlighter.parseOptions=function(i,h){this.showHighlight=true};d.jqplot.Highlighter.postPlotDraw=function(){if(this.plugins.highlighter&&this.plugins.highlighter.highlightCanvas){this.plugins.highlighter.highlightCanvas.resetCanvas();this.plugins.highlighter.highlightCanvas=null}if(this.plugins.highlighter&&this.plugins.highlighter._tooltipElem){this.plugins.highlighter._tooltipElem.emptyForce();this.plugins.highlighter._tooltipElem=null}this.plugins.highlighter.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding,"jqplot-highlight-canvas",this._plotDimensions,this));this.plugins.highlighter.highlightCanvas.setContext();var h=document.createElement("div");this.plugins.highlighter._tooltipElem=d(h);h=null;this.plugins.highlighter._tooltipElem.addClass("jqplot-highlighter-tooltip");this.plugins.highlighter._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem)};d.jqplot.preInitHooks.push(d.jqplot.Highlighter.init);d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Highlighter.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Highlighter.postPlotDraw);function a(m,o){var j=m.plugins.highlighter;var p=m.series[o.seriesIndex];var h=p.markerRenderer;var i=j.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+j.lineWidthAdjust;i.size=h.size+j.sizeAdjust;var l=d.jqplot.getColorComponents(h.color);var n=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B<t.yvalues+1;B++){l.push(h(s,m.data[B]))}if(typeof t.formatString==="string"){switch(t.tooltipAxes){case"both":case"xy":l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"yx":l.push(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"x":z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString,u]);break;case"y":l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;default:l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break}}else{switch(t.tooltipAxes){case"both":case"xy":z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break;case"yx":z="";for(var B=0;B<l.length;B++){z+=l[B]+t.tooltipSeparator}z+=u;break;case"x":z=u;break;case"y":z=l.join(t.tooltipSeparator);break;default:z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break}}}else{var z;if(typeof t.formatString==="string"){z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString].concat(m.data))}else{if(t.tooltipAxes=="both"||t.tooltipAxes=="xy"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}else{if(t.tooltipAxes=="yx"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="x"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="y"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}}}}}}if(d.isFunction(t.tooltipContentEditor)){z=t.tooltipContentEditor(z,m.seriesIndex,m.pointIndex,A)}D.html(z);var C={x:m.gridData[0],y:m.gridData[1]};var v=0;var j=0.707;if(q.markerRenderer.show==true){v=(q.markerRenderer.size+t.sizeAdjust)/2}var o=b;if(q.fillToZero&&q.fill&&m.data[1]<0){o=c}switch(o[e[t.tooltipLocation]]){case"nw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"n":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-v;break;case"ne":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"e":var p=C.x+A._gridPadding.left+t.tooltipOffset+v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;case"se":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"s":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top+t.tooltipOffset+v;break;case"sw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"w":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;default:var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break}D.css("left",p);D.css("top",n);if(t.fadeTooltip){D.stop(true,true).fadeIn(t.tooltipFadeSpeed)}else{D.show()}D=null}function f(n,j,i,p,l){var h=l.plugins.highlighter;var m=l.plugins.cursor;if(h.show){if(p==null&&h.isHighlighting){var o=jQuery.Event("jqplotHighlighterUnhighlight");l.target.trigger(o);var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);if(h.fadeTooltip){h._tooltipElem.fadeOut(h.tooltipFadeSpeed)}else{h._tooltipElem.hide()}if(h.bringSeriesToFront){l.restorePreviousSeriesOrder()}h.isHighlighting=false;h.currentNeighbor=null;q=null}else{if(p!=null&&l.series[p.seriesIndex].showHighlight&&!h.isHighlighting){var o=jQuery.Event("jqplotHighlighterHighlight");o.which=n.which;o.pageX=n.pageX;o.pageY=n.pageY;var k=[p.seriesIndex,p.pointIndex,p.data,l];l.target.trigger(o,k);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(l.series[p.seriesIndex].show&&h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}else{if(p!=null&&h.isHighlighting&&h.currentNeighbor!=p){if(l.series[p.seriesIndex].showHighlight){var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(l.series[p.seriesIndex].show&&h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}}}}}}})(jQuery);
|
js/jqplot.pieRenderer.min.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com
|
2 |
+
jsDate | (c) 2010-2013 Chris Leonello
|
3 |
+
*/(function(e){e.jqplot.PieRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.PieRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.PieRenderer.prototype.constructor=e.jqplot.PieRenderer;e.jqplot.PieRenderer.prototype.init=function(q,u){this.diameter=null;this.padding=20;this.sliceMargin=0;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this.dataLabelPositionFactor=0.52;this.dataLabelNudge=2;this.dataLabelCenterOn=true;this.startAngle=0;this.tickRenderer=e.jqplot.PieTickRenderer;this._drawData=true;this._type="pie";if(q.highlightMouseDown&&q.highlightMouseOver==null){q.highlightMouseOver=false}e.extend(true,this,q);if(this.sliceMargin<0){this.sliceMargin=0}this._diameter=null;this._radius=null;this._sliceAngles=[];this._highlightedPoint=null;if(this.highlightColors.length==0){for(var s=0;s<this.seriesColors.length;s++){var r=e.jqplot.getColorComponents(this.seriesColors[s]);var o=[r[0],r[1],r[2]];var t=o[0]+o[1]+o[2];for(var p=0;p<3;p++){o[p]=(t>570)?o[p]*0.8:o[p]+0.3*(255-o[p]);o[p]=parseInt(o[p],10)}this.highlightColors.push("rgb("+o[0]+","+o[1]+","+o[2]+")")}}this.highlightColorGenerator=new e.jqplot.ColorGenerator(this.highlightColors);u.postParseOptionsHooks.addOnce(m);u.postInitHooks.addOnce(g);u.eventListenerHooks.addOnce("jqplotMouseMove",b);u.eventListenerHooks.addOnce("jqplotMouseDown",a);u.eventListenerHooks.addOnce("jqplotMouseUp",l);u.eventListenerHooks.addOnce("jqplotClick",f);u.eventListenerHooks.addOnce("jqplotRightClick",n);u.postDrawHooks.addOnce(i)};e.jqplot.PieRenderer.prototype.setGridData=function(t){var p=[];var u=[];var o=this.startAngle/180*Math.PI;var s=0;this._drawData=false;for(var r=0;r<this.data.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(this.data[r][1]);u.push([this.data[r][0]]);if(r>0){p[r]+=p[r-1]}s+=this.data[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){u[r][1]=p[r]*q;u[r][2]=this.data[r][1]/s}this.gridData=u};e.jqplot.PieRenderer.prototype.makeGridData=function(t,u){var p=[];var v=[];var s=0;var o=this.startAngle/180*Math.PI;this._drawData=false;for(var r=0;r<t.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(t[r][1]);v.push([t[r][0]]);if(r>0){p[r]+=p[r-1]}s+=t[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){v[r][1]=p[r]*q;v[r][2]=t[r][1]/s}return v};function h(o){return Math.sin((o-(o-Math.PI)/8/Math.PI)/2)}function j(u,t,o,v,r){var w=0;var q=t-u;var s=Math.abs(q);var p=o;if(v==false){p+=r}if(p>0&&s>0.01&&s<6.282){w=parseFloat(p)/2/h(q)}return w}e.jqplot.PieRenderer.prototype.drawSlice=function(B,z,y,u,w){if(this._drawData){var p=this._radius;var A=this.fill;var x=this.lineWidth;var s=this.sliceMargin;if(this.fill==false){s+=this.lineWidth}B.save();B.translate(this._center[0],this._center[1]);var D=j(z,y,this.sliceMargin,this.fill,this.lineWidth);var o=D*Math.cos((z+y)/2);var C=D*Math.sin((z+y)/2);if((y-z)<=Math.PI){p-=D}else{p+=D}B.translate(o,C);if(w){for(var v=0,t=this.shadowDepth;v<t;v++){B.save();B.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));q(p)}for(var v=0,t=this.shadowDepth;v<t;v++){B.restore()}}else{q(p)}B.restore()}function q(r){if(y>6.282+this.startAngle){y=6.282+this.startAngle;if(z>y){z=6.281+this.startAngle}}if(z>=y){return}B.beginPath();B.fillStyle=u;B.strokeStyle=u;B.lineWidth=x;B.arc(0,0,r,z,y,false);B.lineTo(0,0);B.closePath();if(A){B.fill()}else{B.stroke()}}};e.jqplot.PieRenderer.prototype.draw=function(B,z,E,o){var W;var H=(E!=undefined)?E:{};var t=0;var s=0;var N=1;var L=new e.jqplot.ColorGenerator(this.seriesColors);if(E.legendInfo&&E.legendInfo.placement=="insideGrid"){var J=E.legendInfo;switch(J.location){case"nw":t=J.width+J.xoffset;break;case"w":t=J.width+J.xoffset;break;case"sw":t=J.width+J.xoffset;break;case"ne":t=J.width+J.xoffset;N=-1;break;case"e":t=J.width+J.xoffset;N=-1;break;case"se":t=J.width+J.xoffset;N=-1;break;case"n":s=J.height+J.yoffset;break;case"s":s=J.height+J.yoffset;N=-1;break;default:break}}var K=(H.shadow!=undefined)?H.shadow:this.shadow;var A=(H.fill!=undefined)?H.fill:this.fill;var C=B.canvas.width;var I=B.canvas.height;var Q=C-t-2*this.padding;var X=I-s-2*this.padding;var M=Math.min(Q,X);var Y=M;this._sliceAngles=[];var v=this.sliceMargin;if(this.fill==false){v+=this.lineWidth}var q;var G=0;var R,aa,Z,ab;var D=this.startAngle/180*Math.PI;for(var W=0,V=z.length;W<V;W++){aa=(W==0)?D:z[W-1][1]+D;Z=z[W][1]+D;this._sliceAngles.push([aa,Z]);q=j(aa,Z,this.sliceMargin,this.fill,this.lineWidth);if(Math.abs(Z-aa)>Math.PI){G=Math.max(q,G)}}if(this.diameter!=null&&this.diameter>0){this._diameter=this.diameter-2*G}else{this._diameter=Y-2*G}if(this._diameter<6){e.jqplot.log("Diameter of pie too small, not rendering.");return}var S=this._radius=this._diameter/2;this._center=[(C-N*t)/2+N*t+G*Math.cos(D),(I-N*s)/2+N*s+G*Math.sin(D)];if(this.shadow){for(var W=0,V=z.length;W<V;W++){ab="rgba(0,0,0,"+this.shadowAlpha+")";this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],ab,true)}}for(var W=0;W<z.length;W++){this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],L.next(),false);if(this.showDataLabels&&z[W][2]*100>=this.dataLabelThreshold){var F,U=(this._sliceAngles[W][0]+this._sliceAngles[W][1])/2,T;if(this.dataLabels=="label"){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,z[W][0])}else{if(this.dataLabels=="value"){F=this.dataLabelFormatString||"%d";T=e.jqplot.sprintf(F,this.data[W][1])}else{if(this.dataLabels=="percent"){F=this.dataLabelFormatString||"%d%%";T=e.jqplot.sprintf(F,z[W][2]*100)}else{if(this.dataLabels.constructor==Array){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,this.dataLabels[W])}}}}var p=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var P=this._center[0]+Math.cos(U)*p+this.canvas._offsets.left;var O=this._center[1]+Math.sin(U)*p+this.canvas._offsets.top;var u=e('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">'+T+"</div>").insertBefore(o.eventCanvas._elem);if(this.dataLabelCenterOn){P-=u.width()/2;O-=u.height()/2}else{P-=u.width()*Math.sin(U/2);O-=u.height()/2}P=Math.round(P);O=Math.round(O);u.css({left:P,top:O})}}};e.jqplot.PieAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PieAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PieAxisRenderer.prototype.constructor=e.jqplot.PieAxisRenderer;e.jqplot.PieAxisRenderer.prototype.init=function(o){this.tickRenderer=e.jqplot.PieTickRenderer;e.extend(true,this,o);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.PieLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.PieLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.PieLegendRenderer.prototype.constructor=e.jqplot.PieLegendRenderer;e.jqplot.PieLegendRenderer.prototype.init=function(o){this.numberRows=null;this.numberColumns=null;e.extend(true,this,o)};e.jqplot.PieLegendRenderer.prototype.draw=function(){var r=this;if(this.show){var B=this._series;this._elem=e(document.createElement("table"));this._elem.addClass("jqplot-table-legend");var E={position:"absolute"};if(this.background){E.background=this.background}if(this.border){E.border=this.border}if(this.fontSize){E.fontSize=this.fontSize}if(this.fontFamily){E.fontFamily=this.fontFamily}if(this.textColor){E.textColor=this.textColor}if(this.marginTop!=null){E.marginTop=this.marginTop}if(this.marginBottom!=null){E.marginBottom=this.marginBottom}if(this.marginLeft!=null){E.marginLeft=this.marginLeft}if(this.marginRight!=null){E.marginRight=this.marginRight}this._elem.css(E);var I=false,A=false,o,y;var C=B[0];var p=new e.jqplot.ColorGenerator(C.seriesColors);if(C.show){var J=C.data;if(this.numberRows){o=this.numberRows;if(!this.numberColumns){y=Math.ceil(J.length/o)}else{y=this.numberColumns}}else{if(this.numberColumns){y=this.numberColumns;o=Math.ceil(J.length/this.numberColumns)}else{o=J.length;y=1}}var H,G;var q,w,v;var x,z,F;var D=0;var u,t;for(H=0;H<o;H++){q=e(document.createElement("tr"));q.addClass("jqplot-table-legend");if(A){q.prependTo(this._elem)}else{q.appendTo(this._elem)}for(G=0;G<y;G++){if(D<J.length){x=this.labels[D]||J[D][0].toString();F=p.next();if(!A){if(H>0){I=true}else{I=false}}else{if(H==o-1){I=false}else{I=true}}z=(I)?this.rowSpacing:"0";w=e(document.createElement("td"));w.addClass("jqplot-table-legend jqplot-table-legend-swatch");w.css({textAlign:"center",paddingTop:z});u=e(document.createElement("div"));u.addClass("jqplot-table-legend-swatch-outline");t=e(document.createElement("div"));t.addClass("jqplot-table-legend-swatch");t.css({backgroundColor:F,borderColor:F});w.append(u.append(t));v=e(document.createElement("td"));v.addClass("jqplot-table-legend jqplot-table-legend-label");v.css("paddingTop",z);if(this.escapeHtml){v.text(x)}else{v.html(x)}if(A){v.prependTo(q);w.prependTo(q)}else{w.appendTo(q);v.appendTo(q)}I=true}D++}}}}return this._elem};e.jqplot.PieRenderer.prototype.handleMove=function(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];r.target.trigger("jqplotDataMouseOver",o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.pieRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){r.target.trigger("jqplotDataHighlight",o);d(r,o[0],o[1])}}else{if(s==null){k(r)}}};function c(s,r,p){p=p||{};p.axesDefaults=p.axesDefaults||{};p.legend=p.legend||{};p.seriesDefaults=p.seriesDefaults||{};var o=false;if(p.seriesDefaults.renderer==e.jqplot.PieRenderer){o=true}else{if(p.series){for(var q=0;q<p.series.length;q++){if(p.series[q].renderer==e.jqplot.PieRenderer){o=true}}}}if(o){p.axesDefaults.renderer=e.jqplot.PieAxisRenderer;p.legend.renderer=e.jqplot.PieLegendRenderer;p.legend.preDraw=true;p.seriesDefaults.pointLabels={show:false}}}function g(r,q,o){for(var p=0;p<this.series.length;p++){if(this.series[p].renderer.constructor==e.jqplot.PieRenderer){if(this.series[p].highlightMouseOver){this.series[p].highlightMouseDown=false}}}}function m(o){for(var p=0;p<this.series.length;p++){this.series[p].seriesColors=this.seriesColors;this.series[p].colorGenerator=e.jqplot.colorGenerator}}function d(t,r,q){var p=t.series[r];var o=t.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);p._highlightedPoint=q;t.plugins.pieRenderer.highlightedSeriesIndex=r;p.renderer.drawSlice.call(p,o._ctx,p._sliceAngles[q][0],p._sliceAngles[q][1],p.highlightColorGenerator.get(q),false)}function k(q){var o=q.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);for(var p=0;p<q.series.length;p++){q.series[p]._highlightedPoint=null}q.plugins.pieRenderer.highlightedSeriesIndex=null;q.target.trigger("jqplotDataUnhighlight")}function b(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var p=jQuery.Event("jqplotDataMouseOver");p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q);if(t.series[q[0]].highlightMouseOver&&!(q[0]==t.plugins.pieRenderer.highlightedSeriesIndex&&q[1]==t.series[q[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=s.which;o.pageX=s.pageX;o.pageY=s.pageY;t.target.trigger(o,q);d(t,q[0],q[1])}}else{if(u==null){k(t)}}}function a(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];if(s.series[p[0]].highlightMouseDown&&!(p[0]==s.plugins.pieRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);d(s,p[0],p[1])}}else{if(t==null){k(s)}}}function l(q,p,t,s,r){var o=r.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&r.series[o].highlightMouseDown){k(r)}}function f(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}function n(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var o=t.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&t.series[o].highlightMouseDown){k(t)}var p=jQuery.Event("jqplotDataRightClick");p.which=s.which;p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q)}}function i(){if(this.plugins.pieRenderer&&this.plugins.pieRenderer.highlightCanvas){this.plugins.pieRenderer.highlightCanvas.resetCanvas();this.plugins.pieRenderer.highlightCanvas=null}this.plugins.pieRenderer={highlightedSeriesIndex:null};this.plugins.pieRenderer.highlightCanvas=new e.jqplot.GenericCanvas();var p=e(this.targetId+" .jqplot-data-label");if(p.length){e(p[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}var o=this.plugins.pieRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(q){k(q.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.PieTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.PieTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.PieTickRenderer.prototype.constructor=e.jqplot.PieTickRenderer})(jQuery);
|
js/jquery.jqplot.min.js
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* jqplot 1.0.9 | (c) 2009-2016 Chris Leonello | jplot.com
|
2 |
+
jsDate | (c) 2010-2016 Chris Leonello
|
3 |
+
*/
|
4 |
+
!function(a){function b(b){a.jqplot.ElemContainer.call(this),this.name=b,this._series=[],this.show=!1,this.tickRenderer=a.jqplot.AxisTickRenderer,this.tickOptions={},this.labelRenderer=a.jqplot.AxisLabelRenderer,this.labelOptions={},this.label=null,this.showLabel=!0,this.min=null,this.max=null,this.autoscale=!1,this.pad=1.2,this.padMax=null,this.padMin=null,this.ticks=[],this.numberTicks,this.tickInterval,this.renderer=a.jqplot.LinearAxisRenderer,this.rendererOptions={},this.showTicks=!0,this.showTickMarks=!0,this.showMinorTicks=!0,this.drawMajorGridlines=!0,this.drawMinorGridlines=!1,this.drawMajorTickMarks=!0,this.drawMinorTickMarks=!0,this.useSeriesColor=!1,this.borderWidth=null,this.borderColor=null,this.scaleToHiddenSeries=!1,this._dataBounds={min:null,max:null},this._intervalStats=[],this._offsets={min:null,max:null},this._ticks=[],this._label=null,this.syncTicks=null,this.tickSpacing=75,this._min=null,this._max=null,this._tickInterval=null,this._numberTicks=null,this.__ticks=null,this._options={}}function c(b){a.jqplot.ElemContainer.call(this),this.show=!1,this.location="ne",this.labels=[],this.showLabels=!0,this.showSwatches=!0,this.placement="insideGrid",this.xoffset=0,this.yoffset=0,this.border,this.background,this.textColor,this.fontFamily,this.fontSize,this.rowSpacing="0.5em",this.renderer=a.jqplot.TableLegendRenderer,this.rendererOptions={},this.preDraw=!1,this.marginTop=null,this.marginRight=null,this.marginBottom=null,this.marginLeft=null,this.escapeHtml=!1,this._series=[],a.extend(!0,this,b)}function d(b){a.jqplot.ElemContainer.call(this),this.text=b,this.show=!0,this.fontFamily,this.fontSize,this.textAlign,this.textColor,this.renderer=a.jqplot.DivTitleRenderer,this.rendererOptions={},this.escapeHtml=!1}function e(b){b=b||{},a.jqplot.ElemContainer.call(this),this.show=!0,this.xaxis="xaxis",this._xaxis,this.yaxis="yaxis",this._yaxis,this.gridBorderWidth=2,this.renderer=a.jqplot.LineRenderer,this.rendererOptions={},this.data=[],this.gridData=[],this.label="",this.showLabel=!0,this.color,this.negativeColor,this.lineWidth=2.5,this.lineJoin="round",this.lineCap="round",this.linePattern="solid",this.shadow=!0,this.shadowAngle=45,this.shadowOffset=1.25,this.shadowDepth=3,this.shadowAlpha="0.1",this.breakOnNull=!1,this.markerRenderer=a.jqplot.MarkerRenderer,this.markerOptions={},this.showLine=!0,this.showMarker=!0,this.index,this.fill=!1,this.fillColor,this.fillAlpha,this.fillAndStroke=!1,this.disableStack=!1,this._stack=!1,this.neighborThreshold=4,this.fillToZero=!1,this.fillToValue=0,this.fillAxis="y",this.useNegativeColors=!0,this._stackData=[],this._plotData=[],this._plotValues={x:[],y:[]},this._intervals={x:{},y:{}},this._prevPlotData=[],this._prevGridData=[],this._stackAxis="y",this._primaryAxis="_xaxis",this.canvas=new a.jqplot.GenericCanvas,this.shadowCanvas=new a.jqplot.GenericCanvas,this.plugins={},this._sumy=0,this._sumx=0,this._type="",this.step=!1}function f(){a.jqplot.ElemContainer.call(this),this.drawGridlines=!0,this.gridLineColor="#cccccc",this.gridLineWidth=1,this.background="#fffdf6",this.borderColor="#999999",this.borderWidth=2,this.drawBorder=!0,this.shadow=!0,this.shadowAngle=45,this.shadowOffset=1.5,this.shadowWidth=3,this.shadowDepth=3,this.shadowColor=null,this.shadowAlpha="0.07",this._left,this._top,this._right,this._bottom,this._width,this._height,this._axes=[],this.renderer=a.jqplot.CanvasGridRenderer,this.rendererOptions={},this._offsets={top:null,bottom:null,left:null,right:null}}function g(){function h(a){for(var b,c=0;c<a.length;c++)for(var d,e=[a[c].data,a[c]._stackData,a[c]._plotData,a[c]._prevPlotData],f=0;4>f;f++)if(d=!0,b=e[f],"x"==a[c]._stackAxis){for(var g=0;g<b.length;g++)if("number"!=typeof b[g][1]){d=!1;break}d&&b.sort(function(a,b){return a[1]-b[1]})}else{for(var g=0;g<b.length;g++)if("number"!=typeof b[g][0]){d=!1;break}d&&b.sort(function(a,b){return a[0]-b[0]})}}function i(a){var b,c,d=a.data.plot,e=d.eventCanvas._elem.offset(),f={x:a.pageX-e.left,y:a.pageY-e.top},g={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null},h=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"],i=d.axes;for(b=11;b>0;b--)c=h[b-1],i[c].show&&(g[c]=i[c].series_p2u(f[c.charAt(0)]));return{offsets:e,gridPos:f,dataPos:g}}function j(b,c){function d(a,b,c){var d=(b[1]-c[1])/(b[0]-c[0]),e=b[1]-d*b[0],f=a+b[1];return[(f-e)/d,f]}var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x=c.series;for(g=c.seriesStack.length-1;g>=0;g--)switch(e=c.seriesStack[g],h=x[e],u=h._highlightThreshold,h.renderer.constructor){case a.jqplot.BarRenderer:for(j=b.x,k=b.y,f=0;f<h._barPoints.length;f++)if(t=h._barPoints[f],s=h.gridData[f],j>t[0][0]&&j<t[2][0]&&(k>t[2][1]&&k<t[0][1]||k<t[2][1]&&k>t[0][1]))return{seriesIndex:h.index,pointIndex:f,gridData:s,data:h.data[f],points:h._barPoints[f]};break;case a.jqplot.PyramidRenderer:for(j=b.x,k=b.y,f=0;f<h._barPoints.length;f++)if(t=h._barPoints[f],s=h.gridData[f],j>t[0][0]+u[0][0]&&j<t[2][0]+u[2][0]&&k>t[2][1]&&k<t[0][1])return{seriesIndex:h.index,pointIndex:f,gridData:s,data:h.data[f],points:h._barPoints[f]};break;case a.jqplot.DonutRenderer:if(n=h.startAngle/180*Math.PI,j=b.x-h._center[0],k=b.y-h._center[1],i=Math.sqrt(Math.pow(j,2)+Math.pow(k,2)),j>0&&-k>=0?l=2*Math.PI-Math.atan(-k/j):j>0&&0>-k?l=-Math.atan(-k/j):0>j?l=Math.PI-Math.atan(-k/j):0==j&&-k>0?l=3*Math.PI/2:0==j&&0>-k?l=Math.PI/2:0==j&&0==k&&(l=0),n&&(l-=n,0>l?l+=2*Math.PI:l>2*Math.PI&&(l-=2*Math.PI)),m=h.sliceMargin/180*Math.PI,i<h._radius&&i>h._innerRadius)for(f=0;f<h.gridData.length;f++)if(o=f>0?h.gridData[f-1][1]+m:m,p=h.gridData[f][1],l>o&&p>l)return{seriesIndex:h.index,pointIndex:f,gridData:[b.x,b.y],data:h.data[f]};break;case a.jqplot.PieRenderer:if(n=h.startAngle/180*Math.PI,j=b.x-h._center[0],k=b.y-h._center[1],i=Math.sqrt(Math.pow(j,2)+Math.pow(k,2)),j>0&&-k>=0?l=2*Math.PI-Math.atan(-k/j):j>0&&0>-k?l=-Math.atan(-k/j):0>j?l=Math.PI-Math.atan(-k/j):0==j&&-k>0?l=3*Math.PI/2:0==j&&0>-k?l=Math.PI/2:0==j&&0==k&&(l=0),n&&(l-=n,0>l?l+=2*Math.PI:l>2*Math.PI&&(l-=2*Math.PI)),m=h.sliceMargin/180*Math.PI,i<h._radius)for(f=0;f<h.gridData.length;f++)if(o=f>0?h.gridData[f-1][1]+m:m,p=h.gridData[f][1],l>o&&p>l)return{seriesIndex:h.index,pointIndex:f,gridData:[b.x,b.y],data:h.data[f]};break;case a.jqplot.BubbleRenderer:j=b.x,k=b.y;var y=null;if(h.show){for(var f=0;f<h.gridData.length;f++)s=h.gridData[f],r=Math.sqrt((j-s[0])*(j-s[0])+(k-s[1])*(k-s[1])),r<=s[2]&&(q>=r||null==q)&&(q=r,y={seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]});if(null!=y)return y}break;case a.jqplot.FunnelRenderer:j=b.x,k=b.y;var z,A,B,C=h._vertices,D=C[0],E=C[C.length-1];for(z=d(k,D[0],E[3]),A=d(k,D[1],E[2]),f=0;f<C.length;f++)if(B=C[f],k>=B[0][1]&&k<=B[3][1]&&j>=z[0]&&j<=A[0])return{seriesIndex:h.index,pointIndex:f,gridData:null,data:h.data[f]};break;case a.jqplot.LineRenderer:if(j=b.x,k=b.y,i=h.renderer,h.show){if(!(!(h.fill||h.renderer.bands.show&&h.renderer.bands.fill)||c.plugins.highlighter&&c.plugins.highlighter.show)){var F=!1;if(j>h._boundingBox[0][0]&&j<h._boundingBox[1][0]&&k>h._boundingBox[1][1]&&k<h._boundingBox[0][1])for(var G,H=h._areaPoints.length,f=H-1,G=0;H>G;G++){var I=[h._areaPoints[G][0],h._areaPoints[G][1]],J=[h._areaPoints[f][0],h._areaPoints[f][1]];(I[1]<k&&J[1]>=k||J[1]<k&&I[1]>=k)&&I[0]+(k-I[1])/(J[1]-I[1])*(J[0]-I[0])<j&&(F=!F),f=G}if(F)return{seriesIndex:e,pointIndex:null,gridData:h.gridData,data:h.data,points:h._areaPoints};break}w=h.markerRenderer.size/2+h.neighborThreshold,v=w>0?w:0;for(var f=0;f<h.gridData.length;f++)if(s=h.gridData[f],i.constructor==a.jqplot.OHLCRenderer)if(i.candleStick){var K=h._yaxis.series_u2p;if(j>=s[0]-i._bodyWidth/2&&j<=s[0]+i._bodyWidth/2&&k>=K(h.data[f][2])&&k<=K(h.data[f][3]))return{seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]}}else if(i.hlc){var K=h._yaxis.series_u2p;if(j>=s[0]-i._tickLength&&j<=s[0]+i._tickLength&&k>=K(h.data[f][1])&&k<=K(h.data[f][2]))return{seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]}}else{var K=h._yaxis.series_u2p;if(j>=s[0]-i._tickLength&&j<=s[0]+i._tickLength&&k>=K(h.data[f][2])&&k<=K(h.data[f][3]))return{seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]}}else if(null!=s[0]&&null!=s[1]&&(r=Math.sqrt((j-s[0])*(j-s[0])+(k-s[1])*(k-s[1])),v>=r&&(q>=r||null==q)))return q=r,{seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]}}break;default:if(j=b.x,k=b.y,i=h.renderer,h.show){w=h.markerRenderer.size/2+h.neighborThreshold,v=w>0?w:0;for(var f=0;f<h.gridData.length;f++)if(s=h.gridData[f],i.constructor==a.jqplot.OHLCRenderer)if(i.candleStick){var K=h._yaxis.series_u2p;if(j>=s[0]-i._bodyWidth/2&&j<=s[0]+i._bodyWidth/2&&k>=K(h.data[f][2])&&k<=K(h.data[f][3]))return{seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]}}else if(i.hlc){var K=h._yaxis.series_u2p;if(j>=s[0]-i._tickLength&&j<=s[0]+i._tickLength&&k>=K(h.data[f][1])&&k<=K(h.data[f][2]))return{seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]}}else{var K=h._yaxis.series_u2p;if(j>=s[0]-i._tickLength&&j<=s[0]+i._tickLength&&k>=K(h.data[f][2])&&k<=K(h.data[f][3]))return{seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]}}else if(r=Math.sqrt((j-s[0])*(j-s[0])+(k-s[1])*(k-s[1])),v>=r&&(q>=r||null==q))return q=r,{seriesIndex:e,pointIndex:f,gridData:s,data:h.data[f]}}}return null}this.animate=!1,this.animateReplot=!1,this.axes={xaxis:new b("xaxis"),yaxis:new b("yaxis"),x2axis:new b("x2axis"),y2axis:new b("y2axis"),y3axis:new b("y3axis"),y4axis:new b("y4axis"),y5axis:new b("y5axis"),y6axis:new b("y6axis"),y7axis:new b("y7axis"),y8axis:new b("y8axis"),y9axis:new b("y9axis"),yMidAxis:new b("yMidAxis")},this.baseCanvas=new a.jqplot.GenericCanvas,this.captureRightClick=!1,this.data=[],this.dataRenderer,this.dataRendererOptions,this.defaults={axesDefaults:{},axes:{xaxis:{},yaxis:{},x2axis:{},y2axis:{},y3axis:{},y4axis:{},y5axis:{},y6axis:{},y7axis:{},y8axis:{},y9axis:{},yMidAxis:{}},seriesDefaults:{},series:[]},this.defaultAxisStart=1,this.drawIfHidden=!1,this.eventCanvas=new a.jqplot.GenericCanvas,this.fillBetween={series1:null,series2:null,color:null,baseSeries:0,fill:!0},this.fontFamily,this.fontSize,this.grid=new f,this.legend=new c,this.noDataIndicator={show:!1,indicator:"Loading Data...",axes:{xaxis:{min:0,max:10,tickInterval:2,show:!0},yaxis:{min:0,max:12,tickInterval:3,show:!0}}},this.negativeSeriesColors=a.jqplot.config.defaultNegativeColors,this.options={},this.previousSeriesStack=[],this.plugins={},this.series=[],this.seriesStack=[],this.seriesColors=a.jqplot.config.defaultColors,this.sortData=!0,this.stackSeries=!1,this.syncXTicks=!0,this.syncYTicks=!0,this.target=null,this.targetId=null,this.textColor,this.title=new d,this._drawCount=0,this._sumy=0,this._sumx=0,this._stackData=[],this._plotData=[],this._width=null,this._height=null,this._plotDimensions={height:null,width:null},this._gridPadding={top:null,right:null,bottom:null,left:null},this._defaultGridPadding={top:10,right:10,bottom:23,left:10},this._addDomReference=a.jqplot.config.addDomReference,this.preInitHooks=new a.jqplot.HooksManager,this.postInitHooks=new a.jqplot.HooksManager,this.preParseOptionsHooks=new a.jqplot.HooksManager,this.postParseOptionsHooks=new a.jqplot.HooksManager,this.preDrawHooks=new a.jqplot.HooksManager,this.postDrawHooks=new a.jqplot.HooksManager,this.preDrawSeriesHooks=new a.jqplot.HooksManager,this.postDrawSeriesHooks=new a.jqplot.HooksManager,this.preDrawLegendHooks=new a.jqplot.HooksManager,this.addLegendRowHooks=new a.jqplot.HooksManager,this.preSeriesInitHooks=new a.jqplot.HooksManager,this.postSeriesInitHooks=new a.jqplot.HooksManager,this.preParseSeriesOptionsHooks=new a.jqplot.HooksManager,this.postParseSeriesOptionsHooks=new a.jqplot.HooksManager,this.eventListenerHooks=new a.jqplot.EventListenerManager,this.preDrawSeriesShadowHooks=new a.jqplot.HooksManager,this.postDrawSeriesShadowHooks=new a.jqplot.HooksManager,this.colorGenerator=new a.jqplot.ColorGenerator,this.negativeColorGenerator=new a.jqplot.ColorGenerator,this.canvasManager=new a.jqplot.CanvasManager,this.themeEngine=new a.jqplot.ThemeEngine;this.init=function(c,d,e){e=e||{};for(var f=0;f<a.jqplot.preInitHooks.length;f++)a.jqplot.preInitHooks[f].call(this,c,d,e);for(var f=0;f<this.preInitHooks.hooks.length;f++)this.preInitHooks.hooks[f].call(this,c,d,e);if(this.targetId="#"+c,this.target=a("#"+c),this._addDomReference&&this.target.data("jqplot",this),this.target.removeClass("jqplot-error"),!this.target.get(0))throw new Error("No plot target specified");if("static"==this.target.css("position")&&this.target.css("position","relative"),this.target.hasClass("jqplot-target")||this.target.addClass("jqplot-target"),this.target.height())this._height=g=this.target.height();else{var g;g=e&&e.height?parseInt(e.height,10):this.target.attr("data-height")?parseInt(this.target.attr("data-height"),10):parseInt(a.jqplot.config.defaultHeight,10),this._height=g,this.target.css("height",g+"px")}if(this.target.width())this._width=i=this.target.width();else{var i;i=e&&e.width?parseInt(e.width,10):this.target.attr("data-width")?parseInt(this.target.attr("data-width"),10):parseInt(a.jqplot.config.defaultWidth,10),this._width=i,this.target.css("width",i+"px")}for(var f=0,j=G.length;j>f;f++)this.axes[G[f]]=new b(G[f]);if(this._plotDimensions.height=this._height,this._plotDimensions.width=this._width,this.grid._plotDimensions=this._plotDimensions,this.title._plotDimensions=this._plotDimensions,this.baseCanvas._plotDimensions=this._plotDimensions,this.eventCanvas._plotDimensions=this._plotDimensions,this.legend._plotDimensions=this._plotDimensions,this._height<=0||this._width<=0||!this._height||!this._width)throw new Error("Canvas dimension not set");if(e.dataRenderer&&a.isFunction(e.dataRenderer)&&(e.dataRendererOptions&&(this.dataRendererOptions=e.dataRendererOptions),this.dataRenderer=e.dataRenderer,d=this.dataRenderer(d,this,this.dataRendererOptions)),e.noDataIndicator&&a.isPlainObject(e.noDataIndicator)&&a.extend(!0,this.noDataIndicator,e.noDataIndicator),null==d||0==a.isArray(d)||0==d.length||0==a.isArray(d[0])||0==d[0].length){if(0==this.noDataIndicator.show)throw new Error("No data specified");for(var k in this.noDataIndicator.axes)for(var l in this.noDataIndicator.axes[k])this.axes[k][l]=this.noDataIndicator.axes[k][l];this.postDrawHooks.add(function(){var b=this.eventCanvas.getHeight(),c=this.eventCanvas.getWidth(),d=a('<div class="jqplot-noData-container" style="position:absolute;"></div>');this.target.append(d),d.height(b),d.width(c),d.css("top",this.eventCanvas._offsets.top),d.css("left",this.eventCanvas._offsets.left);var e=a('<div class="jqplot-noData-contents" style="text-align:center; position:relative; margin-left:auto; margin-right:auto;"></div>');d.append(e),e.html(this.noDataIndicator.indicator);var f=e.height(),g=e.width();e.height(f),e.width(g),e.css("top",(b-f)/2+"px")})}this.data=a.extend(!0,[],d),this.parseOptions(e),this.textColor&&this.target.css("color",this.textColor),this.fontFamily&&this.target.css("font-family",this.fontFamily),this.fontSize&&this.target.css("font-size",this.fontSize),this.title.init(),this.legend.init(),this._sumy=0,this._sumx=0,this.computePlotData();for(var f=0;f<this.series.length;f++){this.seriesStack.push(f),this.previousSeriesStack.push(f),this.series[f].shadowCanvas._plotDimensions=this._plotDimensions,this.series[f].canvas._plotDimensions=this._plotDimensions;for(var m=0;m<a.jqplot.preSeriesInitHooks.length;m++)a.jqplot.preSeriesInitHooks[m].call(this.series[f],c,this.data,this.options.seriesDefaults,this.options.series[f],this);for(var m=0;m<this.preSeriesInitHooks.hooks.length;m++)this.preSeriesInitHooks.hooks[m].call(this.series[f],c,this.data,this.options.seriesDefaults,this.options.series[f],this);this.series[f]._plotDimensions=this._plotDimensions,this.series[f].init(f,this.grid.borderWidth,this);for(var m=0;m<a.jqplot.postSeriesInitHooks.length;m++)a.jqplot.postSeriesInitHooks[m].call(this.series[f],c,this.data,this.options.seriesDefaults,this.options.series[f],this);for(var m=0;m<this.postSeriesInitHooks.hooks.length;m++)this.postSeriesInitHooks.hooks[m].call(this.series[f],c,this.data,this.options.seriesDefaults,this.options.series[f],this);this._sumy+=this.series[f]._sumy,this._sumx+=this.series[f]._sumx}for(var n,o,f=0,j=G.length;j>f;f++)n=G[f],o=this.axes[n],o._plotDimensions=this._plotDimensions,o.init(),null==this.axes[n].borderColor&&("x"!==n.charAt(0)&&o.useSeriesColor===!0&&o.show?o.borderColor=o._series[0].color:o.borderColor=this.grid.borderColor);this.sortData&&h(this.series),this.grid.init(),this.grid._axes=this.axes,this.legend._series=this.series;for(var f=0;f<a.jqplot.postInitHooks.length;f++)a.jqplot.postInitHooks[f].call(this,c,this.data,e);for(var f=0;f<this.postInitHooks.hooks.length;f++)this.postInitHooks.hooks[f].call(this,c,this.data,e)},this.resetAxesScale=function(b,c){var d=c||{},e=b||this.axes;if(e===!0&&(e=this.axes),a.isArray(e))for(var f=0;f<e.length;f++)this.axes[e[f]].resetScale(d[e[f]]);else if("object"==typeof e)for(var g in e)this.axes[g].resetScale(d[g])},this.reInitialize=function(c,d){for(var e=a.extend(!0,{},this.options,d),f=this.targetId.substr(1),g=null==c?this.data:c,i=0;i<a.jqplot.preInitHooks.length;i++)a.jqplot.preInitHooks[i].call(this,f,g,e);for(var i=0;i<this.preInitHooks.hooks.length;i++)this.preInitHooks.hooks[i].call(this,f,g,e);if(this._height=this.target.height(),this._width=this.target.width(),this._height<=0||this._width<=0||!this._height||!this._width)throw new Error("Target dimension not set");this._plotDimensions.height=this._height,this._plotDimensions.width=this._width,this.grid._plotDimensions=this._plotDimensions,this.title._plotDimensions=this._plotDimensions,this.baseCanvas._plotDimensions=this._plotDimensions,this.eventCanvas._plotDimensions=this._plotDimensions,this.legend._plotDimensions=this._plotDimensions;for(var j,k,l,m,i=0,n=G.length;n>i;i++){j=G[i],m=this.axes[j],k=m._ticks;for(var l=0,o=k.length;o>l;l++){var p=k[l]._elem;p&&(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==F&&window.G_vmlCanvasManager.uninitElement(p.get(0)),p.emptyForce(),p=null,k._elem=null)}k=null,delete m.ticks,delete m._ticks,this.axes[j]=new b(j),this.axes[j]._plotWidth=this._width,this.axes[j]._plotHeight=this._height}c&&(e.dataRenderer&&a.isFunction(e.dataRenderer)&&(e.dataRendererOptions&&(this.dataRendererOptions=e.dataRendererOptions),this.dataRenderer=e.dataRenderer,c=this.dataRenderer(c,this,this.dataRendererOptions)),this.data=a.extend(!0,[],c)),d&&this.parseOptions(e),this.title._plotWidth=this._width,this.textColor&&this.target.css("color",this.textColor),this.fontFamily&&this.target.css("font-family",this.fontFamily),this.fontSize&&this.target.css("font-size",this.fontSize),this.title.init(),this.legend.init(),this._sumy=0,this._sumx=0,this.seriesStack=[],this.previousSeriesStack=[],this.computePlotData();for(var i=0,n=this.series.length;n>i;i++){this.seriesStack.push(i),this.previousSeriesStack.push(i),this.series[i].shadowCanvas._plotDimensions=this._plotDimensions,this.series[i].canvas._plotDimensions=this._plotDimensions;for(var l=0;l<a.jqplot.preSeriesInitHooks.length;l++)a.jqplot.preSeriesInitHooks[l].call(this.series[i],f,this.data,this.options.seriesDefaults,this.options.series[i],this);for(var l=0;l<this.preSeriesInitHooks.hooks.length;l++)this.preSeriesInitHooks.hooks[l].call(this.series[i],f,this.data,this.options.seriesDefaults,this.options.series[i],this);this.series[i]._plotDimensions=this._plotDimensions,this.series[i].init(i,this.grid.borderWidth,this);for(var l=0;l<a.jqplot.postSeriesInitHooks.length;l++)a.jqplot.postSeriesInitHooks[l].call(this.series[i],f,this.data,this.options.seriesDefaults,this.options.series[i],this);for(var l=0;l<this.postSeriesInitHooks.hooks.length;l++)this.postSeriesInitHooks.hooks[l].call(this.series[i],f,this.data,this.options.seriesDefaults,this.options.series[i],this);this._sumy+=this.series[i]._sumy,this._sumx+=this.series[i]._sumx}for(var i=0,n=G.length;n>i;i++)j=G[i],m=this.axes[j],m._plotDimensions=this._plotDimensions,m.init(),null==m.borderColor&&("x"!==j.charAt(0)&&m.useSeriesColor===!0&&m.show?m.borderColor=m._series[0].color:m.borderColor=this.grid.borderColor);this.sortData&&h(this.series),this.grid.init(),this.grid._axes=this.axes,this.legend._series=this.series;for(var i=0,n=a.jqplot.postInitHooks.length;n>i;i++)a.jqplot.postInitHooks[i].call(this,f,this.data,e);for(var i=0,n=this.postInitHooks.hooks.length;n>i;i++)this.postInitHooks.hooks[i].call(this,f,this.data,e)},this.quickInit=function(){if(this._height=this.target.height(),this._width=this.target.width(),this._height<=0||this._width<=0||!this._height||!this._width)throw new Error("Target dimension not set");this._plotDimensions.height=this._height,this._plotDimensions.width=this._width,this.grid._plotDimensions=this._plotDimensions,this.title._plotDimensions=this._plotDimensions,this.baseCanvas._plotDimensions=this._plotDimensions,this.eventCanvas._plotDimensions=this._plotDimensions,this.legend._plotDimensions=this._plotDimensions;for(var b in this.axes)this.axes[b]._plotWidth=this._width,this.axes[b]._plotHeight=this._height;this.title._plotWidth=this._width,this.textColor&&this.target.css("color",this.textColor),this.fontFamily&&this.target.css("font-family",this.fontFamily),this.fontSize&&this.target.css("font-size",this.fontSize),this._sumy=0,this._sumx=0,this.computePlotData();for(var c=0;c<this.series.length;c++)"line"===this.series[c]._type&&this.series[c].renderer.bands.show&&this.series[c].renderer.initBands.call(this.series[c],this.series[c].renderer.options,this),this.series[c]._plotDimensions=this._plotDimensions,this.series[c].canvas._plotDimensions=this._plotDimensions,this._sumy+=this.series[c]._sumy,this._sumx+=this.series[c]._sumx;for(var d,e=0;12>e;e++){d=G[e];for(var f=this.axes[d]._ticks,c=0;c<f.length;c++){var g=f[c]._elem;g&&(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==F&&window.G_vmlCanvasManager.uninitElement(g.get(0)),g.emptyForce(),g=null,f._elem=null)}f=null,this.axes[d]._plotDimensions=this._plotDimensions,this.axes[d]._ticks=[]}this.sortData&&h(this.series),this.grid._axes=this.axes,this.legend._series=this.series},this.computePlotData=function(){this._plotData=[],this._stackData=[];var b,c,d;for(c=0,d=this.series.length;d>c;c++){b=this.series[c],this._plotData.push([]),this._stackData.push([]);var e=b.data;this._plotData[c]=a.extend(!0,[],e),this._stackData[c]=a.extend(!0,[],e),b._plotData=this._plotData[c],b._stackData=this._stackData[c];var f={x:[],y:[]};if(this.stackSeries&&!b.disableStack){b._stack=!0;for(var g="x"===b._stackAxis?0:1,h=0,i=e.length;i>h;h++){var j=e[h][g];if(null==j&&(j=0),this._plotData[c][h][g]=j,this._stackData[c][h][g]=j,c>0)for(var k=c;k--;){var l=this._plotData[k][h][g];if(j*l>=0){this._plotData[c][h][g]+=l,this._stackData[c][h][g]+=l;break}}}}else{for(var m=0;m<b.data.length;m++)f.x.push(b.data[m][0]),f.y.push(b.data[m][1]);this._stackData.push(b.data),this.series[c]._stackData=b.data,this._plotData.push(b.data),b._plotData=b.data,b._plotValues=f}for(c>0&&(b._prevPlotData=this.series[c-1]._plotData),b._sumy=0,b._sumx=0,m=b.data.length-1;m>-1;m--)b._sumy+=b.data[m][1],b._sumx+=b.data[m][0]}},this.populatePlotData=function(b,c){this._plotData=[],this._stackData=[],b._stackData=[],b._plotData=[];var d={x:[],y:[]};if(this.stackSeries&&!b.disableStack){b._stack=!0;for(var e,f,g,h,i="x"===b._stackAxis?0:1,j=a.extend(!0,[],b.data),k=a.extend(!0,[],b.data),l=0;c>l;l++)for(var m=this.series[l].data,n=0;n<m.length;n++)g=m[n],e=null!=g[0]?g[0]:0,f=null!=g[1]?g[1]:0,j[n][0]+=e,j[n][1]+=f,h=i?f:e,b.data[n][i]*h>=0&&(k[n][i]+=h);for(var o=0;o<k.length;o++)d.x.push(k[o][0]),d.y.push(k[o][1]);this._plotData.push(k),this._stackData.push(j),b._stackData=j,b._plotData=k,b._plotValues=d}else{for(var o=0;o<b.data.length;o++)d.x.push(b.data[o][0]),d.y.push(b.data[o][1]);this._stackData.push(b.data),this.series[c]._stackData=b.data,this._plotData.push(b.data),b._plotData=b.data,b._plotValues=d}for(c>0&&(b._prevPlotData=this.series[c-1]._plotData),b._sumy=0,b._sumx=0,o=b.data.length-1;o>-1;o--)b._sumy+=b.data[o][1],b._sumx+=b.data[o][0]},this.getNextSeriesColor=function(a){var b=0,c=a.seriesColors;return function(){return b<c.length?c[b++]:(b=0,c[b++])}}(this),this.parseOptions=function(b){for(var c=0;c<this.preParseOptionsHooks.hooks.length;c++)this.preParseOptionsHooks.hooks[c].call(this,b);for(var c=0;c<a.jqplot.preParseOptionsHooks.length;c++)a.jqplot.preParseOptionsHooks[c].call(this,b);this.options=a.extend(!0,{},this.defaults,b);var d=this.options;if(this.animate=d.animate,this.animateReplot=d.animateReplot,this.stackSeries=d.stackSeries,a.isPlainObject(d.fillBetween))for(var f,g=["series1","series2","color","baseSeries","fill"],c=0,h=g.length;h>c;c++)f=g[c],null!=d.fillBetween[f]&&(this.fillBetween[f]=d.fillBetween[f]);d.seriesColors&&(this.seriesColors=d.seriesColors),d.negativeSeriesColors&&(this.negativeSeriesColors=d.negativeSeriesColors),d.captureRightClick&&(this.captureRightClick=d.captureRightClick),this.defaultAxisStart=b&&null!=b.defaultAxisStart?b.defaultAxisStart:this.defaultAxisStart,this.colorGenerator.setColors(this.seriesColors),this.negativeColorGenerator.setColors(this.negativeSeriesColors),a.extend(!0,this._gridPadding,d.gridPadding),this.sortData=null!=d.sortData?d.sortData:this.sortData;for(var c=0;12>c;c++){var i=G[c],j=this.axes[i];j._options=a.extend(!0,{},d.axesDefaults,d.axes[i]),a.extend(!0,j,d.axesDefaults,d.axes[i]),j._plotWidth=this._width,j._plotHeight=this._height}var k=function(b,c,d){var e,f,g=[];if(c=c||"vertical",a.isArray(b[0]))a.extend(!0,g,b);else for(e=0,f=b.length;f>e;e++)"vertical"==c?g.push([d+e,b[e]]):g.push([b[e],d+e]);return g};this.series=[];for(var c=0;c<this.data.length;c++){for(var l=a.extend(!0,{index:c},{seriesColors:this.seriesColors,negativeSeriesColors:this.negativeSeriesColors},this.options.seriesDefaults,this.options.series[c],{rendererOptions:{animation:{show:this.animate}}}),g=new e(l),m=0;m<a.jqplot.preParseSeriesOptionsHooks.length;m++)a.jqplot.preParseSeriesOptionsHooks[m].call(g,this.options.seriesDefaults,this.options.series[c]);for(var m=0;m<this.preParseSeriesOptionsHooks.hooks.length;m++)this.preParseSeriesOptionsHooks.hooks[m].call(g,this.options.seriesDefaults,this.options.series[c]);a.extend(!0,g,l);var n="vertical";switch(g.renderer===a.jqplot.BarRenderer&&g.rendererOptions&&"horizontal"==g.rendererOptions.barDirection&&(n="horizontal",g._stackAxis="x",g._primaryAxis="_yaxis"),g.data=k(this.data[c],n,this.defaultAxisStart),g.xaxis){case"xaxis":g._xaxis=this.axes.xaxis;break;case"x2axis":g._xaxis=this.axes.x2axis}g._yaxis=this.axes[g.yaxis],g._xaxis._series.push(g),g._yaxis._series.push(g),g.show?(g._xaxis.show=!0,g._yaxis.show=!0):(g._xaxis.scaleToHiddenSeries&&(g._xaxis.show=!0),g._yaxis.scaleToHiddenSeries&&(g._yaxis.show=!0)),g.label||(g.label="Series "+(c+1).toString()),this.series.push(g);for(var m=0;m<a.jqplot.postParseSeriesOptionsHooks.length;m++)a.jqplot.postParseSeriesOptionsHooks[m].call(this.series[c],this.options.seriesDefaults,this.options.series[c]);for(var m=0;m<this.postParseSeriesOptionsHooks.hooks.length;m++)this.postParseSeriesOptionsHooks.hooks[m].call(this.series[c],this.options.seriesDefaults,this.options.series[c])}a.extend(!0,this.grid,this.options.grid);for(var c=0,h=G.length;h>c;c++){var i=G[c],j=this.axes[i];null==j.borderWidth&&(j.borderWidth=this.grid.borderWidth)}"string"==typeof this.options.title?this.title.text=this.options.title:"object"==typeof this.options.title&&a.extend(!0,this.title,this.options.title),this.title._plotWidth=this._width,this.legend.setOptions(this.options.legend);for(var c=0;c<a.jqplot.postParseOptionsHooks.length;c++)a.jqplot.postParseOptionsHooks[c].call(this,b);for(var c=0;c<this.postParseOptionsHooks.hooks.length;c++)this.postParseOptionsHooks.hooks[c].call(this,b)},this.destroy=function(){this.canvasManager.freeAllCanvases(),this.eventCanvas&&this.eventCanvas._elem&&this.eventCanvas._elem.unbind(),this.target.empty(),this.target[0].innerHTML=""},this.replot=function(b){var c=b||{},d=c.data||null,e=c.clear===!1?!1:!0,f=c.resetAxes||!1;delete c.data,delete c.clear,delete c.resetAxes,this.target.trigger("jqplotPreReplot"),e&&this.destroy(),d||!a.isEmptyObject(c)?this.reInitialize(d,c):this.quickInit(),f&&this.resetAxesScale(f,c.axes),this.draw(),this.target.trigger("jqplotPostReplot")},this.redraw=function(a){a=null!=a?a:!0,this.target.trigger("jqplotPreRedraw"),a&&(this.canvasManager.freeAllCanvases(),this.eventCanvas._elem.unbind(),this.target.empty());for(var b in this.axes)this.axes[b]._ticks=[];this.computePlotData(),this._sumy=0,this._sumx=0;for(var c=0,d=this.series.length;d>c;c++)this._sumy+=this.series[c]._sumy,this._sumx+=this.series[c]._sumx;this.draw(),this.target.trigger("jqplotPostRedraw")},this.draw=function(){if(this.drawIfHidden||this.target.is(":visible")){this.target.trigger("jqplotPreDraw");var b,c,d;for(b=0,d=a.jqplot.preDrawHooks.length;d>b;b++)a.jqplot.preDrawHooks[b].call(this);for(b=0,d=this.preDrawHooks.hooks.length;d>b;b++)this.preDrawHooks.hooks[b].apply(this,this.preDrawSeriesHooks.args[b]);this.target.append(this.baseCanvas.createElement({left:0,right:0,top:0,bottom:0},"jqplot-base-canvas",null,this)),this.baseCanvas.setContext(),this.target.append(this.title.draw()),this.title.pack({top:0,left:0});var e=this.legend.draw({},this),f={top:0,left:0,bottom:0,right:0};if("outsideGrid"==this.legend.placement){switch(this.target.append(e),this.legend.location){case"n":f.top+=this.legend.getHeight();break;case"s":f.bottom+=this.legend.getHeight();break;case"ne":case"e":case"se":f.right+=this.legend.getWidth();break;case"nw":case"w":case"sw":f.left+=this.legend.getWidth();break;default:f.right+=this.legend.getWidth()}e=e.detach()}var g,h=this.axes;for(b=0;12>b;b++)g=G[b],this.target.append(h[g].draw(this.baseCanvas._ctx,this)),h[g].set();h.yaxis.show&&(f.left+=h.yaxis.getWidth());var i,j=["y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"],k=[0,0,0,0,0,0,0,0],l=0;for(i=0;8>i;i++)h[j[i]].show&&(l+=h[j[i]].getWidth(),k[i]=l);if(f.right+=l,h.x2axis.show&&(f.top+=h.x2axis.getHeight()),this.title.show&&(f.top+=this.title.getHeight()),h.xaxis.show&&(f.bottom+=h.xaxis.getHeight()),this.options.gridDimensions&&a.isPlainObject(this.options.gridDimensions)){var m=parseInt(this.options.gridDimensions.width,10)||0,n=parseInt(this.options.gridDimensions.height,10)||0,o=(this._width-f.left-f.right-m)/2,p=(this._height-f.top-f.bottom-n)/2;p>=0&&o>=0&&(f.top+=p,f.bottom+=p,f.left+=o,f.right+=o)}var q=["top","bottom","left","right"];for(var i in q)null==this._gridPadding[q[i]]&&f[q[i]]>0?this._gridPadding[q[i]]=f[q[i]]:null==this._gridPadding[q[i]]&&(this._gridPadding[q[i]]=this._defaultGridPadding[q[i]]);var r=this._gridPadding;for("outsideGrid"===this.legend.placement&&(r={top:this.title.getHeight(),left:0,right:0,bottom:0},"s"===this.legend.location&&(r.left=this._gridPadding.left,r.right=this._gridPadding.right)),h.xaxis.pack({position:"absolute",bottom:this._gridPadding.bottom-h.xaxis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right}),h.yaxis.pack({position:"absolute",top:0,left:this._gridPadding.left-h.yaxis.getWidth(),height:this._height},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top}),h.x2axis.pack({position:"absolute",top:this._gridPadding.top-h.x2axis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right}),b=8;b>0;b--)h[j[b-1]].pack({position:"absolute",top:0,right:this._gridPadding.right-k[b-1]},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});var s=(this._width-this._gridPadding.left-this._gridPadding.right)/2+this._gridPadding.left-h.yMidAxis.getWidth()/2;h.yMidAxis.pack({position:"absolute",top:0,left:s,zIndex:9,textAlign:"center"},{min:this._height-this._gridPadding.bottom,
|
5 |
+
max:this._gridPadding.top}),this.target.append(this.grid.createElement(this._gridPadding,this)),this.grid.draw();var t=this.series,u=t.length;for(b=0,d=u;d>b;b++)c=this.seriesStack[b],this.target.append(t[c].shadowCanvas.createElement(this._gridPadding,"jqplot-series-shadowCanvas",null,this)),t[c].shadowCanvas.setContext(),t[c].shadowCanvas._elem.data("seriesIndex",c);for(b=0,d=u;d>b;b++)c=this.seriesStack[b],this.target.append(t[c].canvas.createElement(this._gridPadding,"jqplot-series-canvas",null,this)),t[c].canvas.setContext(),t[c].canvas._elem.data("seriesIndex",c);this.target.append(this.eventCanvas.createElement(this._gridPadding,"jqplot-event-canvas",null,this)),this.eventCanvas.setContext(),this.eventCanvas._ctx.fillStyle="rgba(0,0,0,0)",this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width,this.eventCanvas._ctx.canvas.height),this.bindCustomEvents(),this.legend.preDraw?(this.eventCanvas._elem.before(e),this.legend.pack(r),this.legend._elem?this.drawSeries({legendInfo:{location:this.legend.location,placement:this.legend.placement,width:this.legend.getWidth(),height:this.legend.getHeight(),xoffset:this.legend.xoffset,yoffset:this.legend.yoffset}}):this.drawSeries()):(this.drawSeries(),u&&a(t[u-1].canvas._elem).after(e),this.legend.pack(r));for(var b=0,d=a.jqplot.eventListenerHooks.length;d>b;b++)this.eventCanvas._elem.bind(a.jqplot.eventListenerHooks[b][0],{plot:this},a.jqplot.eventListenerHooks[b][1]);for(var b=0,d=this.eventListenerHooks.hooks.length;d>b;b++)this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[b][0],{plot:this},this.eventListenerHooks.hooks[b][1]);var v=this.fillBetween;if("number"==typeof v.series1)v.fill&&v.series1!==v.series2&&v.series1<u&&v.series2<u&&"line"===t[v.series1]._type&&"line"===t[v.series2]._type&&this.doFillBetweenLines();else if(null!=v.series1&&null!=v.series2){var w=!1;if(v.series1.length===v.series2.length)for(var x=0,y=0,z=0;z<v.series1.length;z++){if(x=v.series1[z],y=v.series2[z],!(x!==y&&u>x&&u>y&&"line"===t[x]._type&&"line"===t[y]._type)){w=!1;break}w=!0}v.fill&&w&&this.doFillBetweenLines()}for(var b=0,d=a.jqplot.postDrawHooks.length;d>b;b++)a.jqplot.postDrawHooks[b].call(this);for(var b=0,d=this.postDrawHooks.hooks.length;d>b;b++)this.postDrawHooks.hooks[b].apply(this,this.postDrawHooks.args[b]);this.target.is(":visible")&&(this._drawCount+=1);var A,B,C,D;for(b=0,d=u;d>b;b++)A=t[b],B=A.renderer,C=".jqplot-point-label.jqplot-series-"+b,B.animation&&B.animation._supported&&B.animation.show&&(this._drawCount<2||this.animateReplot)&&(D=this.target.find(C),D.stop(!0,!0).hide(),A.canvas._elem.stop(!0,!0).hide(),A.shadowCanvas._elem.stop(!0,!0).hide(),A.canvas._elem.jqplotEffect("blind",{mode:"show",direction:B.animation.direction},B.animation.speed),A.shadowCanvas._elem.jqplotEffect("blind",{mode:"show",direction:B.animation.direction},B.animation.speed),D.fadeIn(.8*B.animation.speed));D=null,this.target.trigger("jqplotPostDraw",[this])}},g.prototype.doFillBetweenLines=function(){function a(a,e){var f=c[a],g=c[e];if(g.renderer.smooth)var h=g.renderer._smoothedData.slice(0).reverse();else var h=g.gridData.slice(0).reverse();if(f.renderer.smooth)var i=f.renderer._smoothedData.concat(h);else var i=f.gridData.concat(h);var j=null!==b.color?b.color:c[d].fillColor,k=null!==b.baseSeries?b.baseSeries:a,l=c[k].renderer.shapeRenderer,m={fillStyle:j,fill:!0,closePath:!0};l.draw(f.shadowCanvas._ctx,i,m)}var b=this.fillBetween,c=this.series,d=b.series1,e=b.series2,f=0,g=0;if("number"==typeof d&&"number"==typeof e)f=e>d?d:e,g=e>d?e:d,a(f,g);else for(var h=0;h<d.length;h++)f=d[h]<e[h]?d[h]:e[h],g=e[h]>d[h]?e[h]:d[h],a(f,g)},this.bindCustomEvents=function(){this.eventCanvas._elem.bind("click",{plot:this},this.onClick),this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick),this.eventCanvas._elem.bind("mousedown",{plot:this},this.onMouseDown),this.eventCanvas._elem.bind("mousemove",{plot:this},this.onMouseMove),this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter),this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave),this.captureRightClick?(this.eventCanvas._elem.bind("mouseup",{plot:this},this.onRightClick),this.eventCanvas._elem.get(0).oncontextmenu=function(){return!1}):this.eventCanvas._elem.bind("mouseup",{plot:this},this.onMouseUp)},this.onClick=function(b){var c=i(b),d=b.data.plot,e=j(c.gridPos,d),f=a.Event("jqplotClick");f.pageX=b.pageX,f.pageY=b.pageY,a(this).trigger(f,[c.gridPos,c.dataPos,e,d])},this.onDblClick=function(b){var c=i(b),d=b.data.plot,e=j(c.gridPos,d),f=a.Event("jqplotDblClick");f.pageX=b.pageX,f.pageY=b.pageY,a(this).trigger(f,[c.gridPos,c.dataPos,e,d])},this.onMouseDown=function(b){var c=i(b),d=b.data.plot,e=j(c.gridPos,d),f=a.Event("jqplotMouseDown");f.pageX=b.pageX,f.pageY=b.pageY,a(this).trigger(f,[c.gridPos,c.dataPos,e,d])},this.onMouseUp=function(b){var c=i(b),d=a.Event("jqplotMouseUp");d.pageX=b.pageX,d.pageY=b.pageY,a(this).trigger(d,[c.gridPos,c.dataPos,null,b.data.plot])},this.onRightClick=function(b){var c=i(b),d=b.data.plot,e=j(c.gridPos,d);if(d.captureRightClick)if(3==b.which){var f=a.Event("jqplotRightClick");f.pageX=b.pageX,f.pageY=b.pageY,a(this).trigger(f,[c.gridPos,c.dataPos,e,d])}else{var f=a.Event("jqplotMouseUp");f.pageX=b.pageX,f.pageY=b.pageY,a(this).trigger(f,[c.gridPos,c.dataPos,e,d])}},this.onMouseMove=function(b){var c=i(b),d=b.data.plot,e=j(c.gridPos,d),f=a.Event("jqplotMouseMove");f.pageX=b.pageX,f.pageY=b.pageY,a(this).trigger(f,[c.gridPos,c.dataPos,e,d])},this.onMouseEnter=function(b){var c=i(b),d=b.data.plot,e=a.Event("jqplotMouseEnter");e.pageX=b.pageX,e.pageY=b.pageY,e.relatedTarget=b.relatedTarget,a(this).trigger(e,[c.gridPos,c.dataPos,null,d])},this.onMouseLeave=function(b){var c=i(b),d=b.data.plot,e=a.Event("jqplotMouseLeave");e.pageX=b.pageX,e.pageY=b.pageY,e.relatedTarget=b.relatedTarget,a(this).trigger(e,[c.gridPos,c.dataPos,null,d])},this.drawSeries=function(b,c){var d,e,f;if(c="number"==typeof b&&null==c?b:c,b="object"==typeof b?b:{},c!=F)e=this.series[c],f=e.shadowCanvas._ctx,f.clearRect(0,0,f.canvas.width,f.canvas.height),e.drawShadow(f,b,this),f=e.canvas._ctx,f.clearRect(0,0,f.canvas.width,f.canvas.height),e.draw(f,b,this),e.renderer.constructor==a.jqplot.BezierCurveRenderer&&c<this.series.length-1&&this.drawSeries(c+1);else for(d=0;d<this.series.length;d++)e=this.series[d],f=e.shadowCanvas._ctx,f.clearRect(0,0,f.canvas.width,f.canvas.height),e.drawShadow(f,b,this),f=e.canvas._ctx,f.clearRect(0,0,f.canvas.width,f.canvas.height),e.draw(f,b,this);b=c=d=e=f=null},this.moveSeriesToFront=function(b){b=parseInt(b,10);var c=a.inArray(b,this.seriesStack);if(-1!=c){if(c==this.seriesStack.length-1)return void(this.previousSeriesStack=this.seriesStack.slice(0));var d=this.seriesStack[this.seriesStack.length-1],e=this.series[b].canvas._elem.detach(),f=this.series[b].shadowCanvas._elem.detach();this.series[d].shadowCanvas._elem.after(f),this.series[d].canvas._elem.after(e),this.previousSeriesStack=this.seriesStack.slice(0),this.seriesStack.splice(c,1),this.seriesStack.push(b)}},this.moveSeriesToBack=function(b){b=parseInt(b,10);var c=a.inArray(b,this.seriesStack);if(0!=c&&-1!=c){var d=this.seriesStack[0],e=this.series[b].canvas._elem.detach(),f=this.series[b].shadowCanvas._elem.detach();this.series[d].shadowCanvas._elem.before(f),this.series[d].canvas._elem.before(e),this.previousSeriesStack=this.seriesStack.slice(0),this.seriesStack.splice(c,1),this.seriesStack.unshift(b)}},this.restorePreviousSeriesOrder=function(){var a,b,c,d,e,f;if(this.seriesStack!=this.previousSeriesStack){for(a=1;a<this.previousSeriesStack.length;a++)e=this.previousSeriesStack[a],f=this.previousSeriesStack[a-1],b=this.series[e].canvas._elem.detach(),c=this.series[e].shadowCanvas._elem.detach(),this.series[f].shadowCanvas._elem.after(c),this.series[f].canvas._elem.after(b);d=this.seriesStack.slice(0),this.seriesStack=this.previousSeriesStack.slice(0),this.previousSeriesStack=d}},this.restoreOriginalSeriesOrder=function(){var a,b,c,d=[];for(a=0;a<this.series.length;a++)d.push(a);if(this.seriesStack!=d)for(this.previousSeriesStack=this.seriesStack.slice(0),this.seriesStack=d,a=1;a<this.seriesStack.length;a++)b=this.series[a].canvas._elem.detach(),c=this.series[a].shadowCanvas._elem.detach(),this.series[a-1].shadowCanvas._elem.after(c),this.series[a-1].canvas._elem.after(b)},this.activateTheme=function(a){this.themeEngine.activate(this,a)}}function h(a,b){return(3.4182054+b)*Math.pow(a,-.3534992)}function i(a){var b=(Math.exp(2*a)-1)/(Math.exp(2*a)+1);return b}function j(a){function b(a,b){return a-b==0?Math.pow(10,10):a-b}var c=this.renderer.smooth,d=this.canvas.getWidth(),e=this._xaxis.series_p2u,f=this._yaxis.series_p2u,g=null,i=a.length/d,j=[],k=[];g=isNaN(parseFloat(c))?h(i,.5):parseFloat(c);for(var l=[],m=[],n=0,o=a.length;o>n;n++)l.push(a[n][1]),m.push(a[n][0]);for(var p,q,r,s,t=a.length-1,u=1,v=a.length;v>u;u++){for(var w=[],x=[],y=0;2>y;y++){var n=u-1+y;0==n||n==t?w[y]=Math.pow(10,10):l[n+1]-l[n]==0||l[n]-l[n-1]==0?w[y]=0:(m[n+1]-m[n])/(l[n+1]-l[n])+(m[n]-m[n-1])/(l[n]-l[n-1])==0?w[y]=0:(l[n+1]-l[n])*(l[n]-l[n-1])<0?w[y]=0:w[y]=2/(b(m[n+1],m[n])/(l[n+1]-l[n])+b(m[n],m[n-1])/(l[n]-l[n-1]))}1==u?w[0]=1.5*(l[1]-l[0])/b(m[1],m[0])-w[1]/2:u==t&&(w[1]=1.5*(l[t]-l[t-1])/b(m[t],m[t-1])-w[0]/2),x[0]=-2*(w[1]+2*w[0])/b(m[u],m[u-1])+6*(l[u]-l[u-1])/Math.pow(b(m[u],m[u-1]),2),x[1]=2*(2*w[1]+w[0])/b(m[u],m[u-1])-6*(l[u]-l[u-1])/Math.pow(b(m[u],m[u-1]),2),s=1/6*(x[1]-x[0])/b(m[u],m[u-1]),r=.5*(m[u]*x[0]-m[u-1]*x[1])/b(m[u],m[u-1]),q=(l[u]-l[u-1]-r*(Math.pow(m[u],2)-Math.pow(m[u-1],2))-s*(Math.pow(m[u],3)-Math.pow(m[u-1],3)))/b(m[u],m[u-1]),p=l[u-1]-q*m[u-1]-r*Math.pow(m[u-1],2)-s*Math.pow(m[u-1],3);for(var z,A,B=(m[u]-m[u-1])/g,y=0,o=g;o>y;y++)z=[],A=m[u-1]+y*B,z.push(A),z.push(p+q*A+r*Math.pow(A,2)+s*Math.pow(A,3)),j.push(z),k.push([e(z[0]),f(z[1])])}return j.push(a[n]),k.push([e(a[n][0]),f(a[n][1])]),[j,k]}function k(a){var b,c,d,e,f,g,j,k,l,m,n,o,p,q,r,s,t,u,v=this.renderer.smooth,w=this.renderer.tension,x=this.canvas.getWidth(),y=this._xaxis.series_p2u,z=this._yaxis.series_p2u,A=null,B=null,C=null,D=null,E=null,F=null,G=null,H=a.length/x,I=[],J=[];A=isNaN(parseFloat(v))?h(H,.5):parseFloat(v),isNaN(parseFloat(w))||(w=parseFloat(w));for(var K=0,L=a.length-1;L>K;K++)for(null===w?(E=Math.abs((a[K+1][1]-a[K][1])/(a[K+1][0]-a[K][0])),q=.3,r=.6,s=(r-q)/2,t=2.5,u=-1.4,G=E/t+u,C=s*i(G)-s*i(u)+q,K>0&&(F=Math.abs((a[K][1]-a[K-1][1])/(a[K][0]-a[K-1][0]))),G=F/t+u,D=s*i(G)-s*i(u)+q,B=(C+D)/2):B=w,b=0;A>b;b++)c=b/A,d=(1+2*c)*Math.pow(1-c,2),e=c*Math.pow(1-c,2),f=Math.pow(c,2)*(3-2*c),g=Math.pow(c,2)*(c-1),a[K-1]?(j=B*(a[K+1][0]-a[K-1][0]),k=B*(a[K+1][1]-a[K-1][1])):(j=B*(a[K+1][0]-a[K][0]),k=B*(a[K+1][1]-a[K][1])),a[K+2]?(l=B*(a[K+2][0]-a[K][0]),m=B*(a[K+2][1]-a[K][1])):(l=B*(a[K+1][0]-a[K][0]),m=B*(a[K+1][1]-a[K][1])),n=d*a[K][0]+f*a[K+1][0]+e*j+g*l,o=d*a[K][1]+f*a[K+1][1]+e*k+g*m,p=[n,o],I.push(p),J.push([y(n),z(o)]);return I.push(a[L]),J.push([y(a[L][0]),z(a[L][1])]),[I,J]}function l(b,c,d){for(var e=0;e<this.series.length;e++)this.series[e].renderer.constructor==a.jqplot.LineRenderer&&this.series[e].highlightMouseOver&&(this.series[e].highlightMouseDown=!1)}function m(){this.plugins.lineRenderer&&this.plugins.lineRenderer.highlightCanvas&&(this.plugins.lineRenderer.highlightCanvas.resetCanvas(),this.plugins.lineRenderer.highlightCanvas=null),this.plugins.lineRenderer.highlightedSeriesIndex=null,this.plugins.lineRenderer.highlightCanvas=new a.jqplot.GenericCanvas,this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-lineRenderer-highlight-canvas",this._plotDimensions,this)),this.plugins.lineRenderer.highlightCanvas.setContext(),this.eventCanvas._elem.bind("mouseleave",{plot:this},function(a){o(a.data.plot)})}function n(a,b,c,d){var e=a.series[b],f=a.plugins.lineRenderer.highlightCanvas;f._ctx.clearRect(0,0,f._ctx.canvas.width,f._ctx.canvas.height),e._highlightedPoint=c,a.plugins.lineRenderer.highlightedSeriesIndex=b;var g={fillStyle:e.highlightColor};"line"===e.type&&e.renderer.bands.show&&(g.fill=!0,g.closePath=!0),e.renderer.shapeRenderer.draw(f._ctx,d,g),f=null}function o(a){var b=a.plugins.lineRenderer.highlightCanvas;b._ctx.clearRect(0,0,b._ctx.canvas.width,b._ctx.canvas.height);for(var c=0;c<a.series.length;c++)a.series[c]._highlightedPoint=null;a.plugins.lineRenderer.highlightedSeriesIndex=null,a.target.trigger("jqplotDataUnhighlight"),b=null}function p(a,b,c,d,e){if(d){var f=[d.seriesIndex,d.pointIndex,d.data],g=jQuery.Event("jqplotDataMouseOver");if(g.pageX=a.pageX,g.pageY=a.pageY,e.target.trigger(g,f),e.series[f[0]].highlightMouseOver&&f[0]!=e.plugins.lineRenderer.highlightedSeriesIndex){var h=jQuery.Event("jqplotDataHighlight");h.which=a.which,h.pageX=a.pageX,h.pageY=a.pageY,e.target.trigger(h,f),n(e,d.seriesIndex,d.pointIndex,d.points)}}else null==d&&o(e)}function q(a,b,c,d,e){if(d){var f=[d.seriesIndex,d.pointIndex,d.data];if(e.series[f[0]].highlightMouseDown&&f[0]!=e.plugins.lineRenderer.highlightedSeriesIndex){var g=jQuery.Event("jqplotDataHighlight");g.which=a.which,g.pageX=a.pageX,g.pageY=a.pageY,e.target.trigger(g,f),n(e,d.seriesIndex,d.pointIndex,d.points)}}else null==d&&o(e)}function r(a,b,c,d,e){var f=e.plugins.lineRenderer.highlightedSeriesIndex;null!=f&&e.series[f].highlightMouseDown&&o(e)}function s(a,b,c,d,e){if(d){var f=[d.seriesIndex,d.pointIndex,d.data],g=jQuery.Event("jqplotDataClick");g.which=a.which,g.pageX=a.pageX,g.pageY=a.pageY,e.target.trigger(g,f)}}function t(a,b,c,d,e){if(d){var f=[d.seriesIndex,d.pointIndex,d.data],g=e.plugins.lineRenderer.highlightedSeriesIndex;null!=g&&e.series[g].highlightMouseDown&&o(e);var h=jQuery.Event("jqplotDataRightClick");h.which=a.which,h.pageX=a.pageX,h.pageY=a.pageY,e.target.trigger(h,f)}}function u(a){var b;if(a=Math.abs(a),a>=10)b="%d";else if(a>1)b=a===parseInt(a,10)?"%d":"%.1f";else{var c=-Math.floor(Math.log(a)/Math.LN10);b="%."+c+"f"}return b}function v(b,c,d){for(var e,f,g,h,i,j,k,l=Math.floor(d/2),m=Math.ceil(1.5*d),n=Number.MAX_VALUE,o=c-b,p=a.jqplot.getSignificantFigures,q=0,r=m-l+1;r>q;q++)j=l+q,e=o/(j-1),f=p(e),e=Math.abs(d-j)+f.digitsRight,n>e?(n=e,g=j,k=f.digitsRight):e===n&&f.digitsRight<k&&(g=j,k=f.digitsRight);return h=Math.max(k,Math.max(p(b).digitsRight,p(c).digitsRight)),i=0===h?"%d":"%."+h+"f",e=o/(g-1),[b,c,g,i,e]}function w(a,b){b=b||7;var c,d=a/(b-1),e=Math.pow(10,Math.floor(Math.log(d)/Math.LN10)),f=d/e;return c=1>e?f>5?10*e:f>2?5*e:f>1?2*e:e:f>5?10*e:f>4?5*e:f>3?4*e:f>2?3*e:f>1?2*e:e}function x(a,b){b=b||1;var c,d=Math.floor(Math.log(a)/Math.LN10),e=Math.pow(10,d),f=a/e;return f/=b,c=.38>=f?.1:1.6>=f?.2:4>=f?.5:8>=f?1:16>=f?2:5,c*e}function y(a,b){var c,d,e=Math.floor(Math.log(a)/Math.LN10),f=Math.pow(10,e),g=a/f;return g/=b,d=.38>=g?.1:1.6>=g?.2:4>=g?.5:8>=g?1:16>=g?2:5,c=d*f,[c,d,f]}function z(a,b){return a-b}function A(a){if(null==a||"object"!=typeof a)return a;var b=new a.constructor;for(var c in a)b[c]=A(a[c]);return b}function B(a,b){if(null!=b&&"object"==typeof b)for(var c in b)"highlightColors"==c&&(a[c]=A(b[c])),null!=b[c]&&"object"==typeof b[c]?(a.hasOwnProperty(c)||(a[c]={}),B(a[c],b[c])):a[c]=b[c]}function C(a,b){if(b.indexOf)return b.indexOf(a);for(var c=0,d=b.length;d>c;c++)if(b[c]===a)return c;return-1}function D(a){return null===a?"[object Null]":Object.prototype.toString.call(a)}function E(b,c,d,e){return a.isPlainObject(b)?b:(b={effect:b},c===F&&(c={}),a.isFunction(c)&&(e=c,d=null,c={}),("number"===a.type(c)||a.fx.speeds[c])&&(e=d,d=c,c={}),a.isFunction(d)&&(e=d,d=null),c&&a.extend(b,c),d=d||c.duration,b.duration=a.fx.off?0:"number"==typeof d?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,b.complete=e||c.complete,b)}var F;a.fn.emptyForce=function(){for(var b,c=0;null!=(b=a(this)[c]);c++){if(1===b.nodeType&&a.cleanData(b.getElementsByTagName("*")),a.jqplot.use_excanvas)b.outerHTML="";else for(;b.firstChild;)b.removeChild(b.firstChild);b=null}return a(this)},a.fn.removeChildForce=function(a){for(;a.firstChild;)this.removeChildForce(a.firstChild),a.removeChild(a.firstChild)},a.fn.jqplot=function(){for(var b=[],c=[],d=0,e=arguments.length;e>d;d++)a.isArray(arguments[d])?b.push(arguments[d]):a.isPlainObject(arguments[d])&&c.push(arguments[d]);return this.each(function(d){var e,f,g,h,i=a(this),j=b.length,k=c.length;g=j>d?b[d]:j?b[j-1]:null,h=k>d?c[d]:k?c[k-1]:null,e=i.attr("id"),e===F&&(e="jqplot_target_"+a.jqplot.targetCounter++,i.attr("id",e)),f=a.jqplot(e,g,h),i.data("jqplot",f)})},a.jqplot=function(b,c,d){var e=null,f=null;3===arguments.length?(e=c,f=d):2===arguments.length&&(a.isArray(c)?e=c:a.isPlainObject(c)&&(f=c)),null===e&&null!==f&&f.data&&(e=f.data);var h=new g;if(a("#"+b).removeClass("jqplot-error"),!a.jqplot.config.catchErrors)return h.init(b,e,f),h.draw(),h.themeEngine.init.call(h),h;try{return h.init(b,e,f),h.draw(),h.themeEngine.init.call(h),h}catch(i){var j=a.jqplot.config.errorMessage||i.message;a("#"+b).append('<div class="jqplot-error-message">'+j+"</div>"),a("#"+b).addClass("jqplot-error"),document.getElementById(b).style.background=a.jqplot.config.errorBackground,document.getElementById(b).style.border=a.jqplot.config.errorBorder,document.getElementById(b).style.fontFamily=a.jqplot.config.errorFontFamily,document.getElementById(b).style.fontSize=a.jqplot.config.errorFontSize,document.getElementById(b).style.fontStyle=a.jqplot.config.errorFontStyle,document.getElementById(b).style.fontWeight=a.jqplot.config.errorFontWeight}},a.jqplot.version="1.0.9",a.jqplot.revision="d96a669",a.jqplot.targetCounter=1,a.jqplot.CanvasManager=function(){"undefined"==typeof a.jqplot.CanvasManager.canvases&&(a.jqplot.CanvasManager.canvases=[],a.jqplot.CanvasManager.free=[]);var b=[];this.getCanvas=function(){var c,d=!0;if(!a.jqplot.use_excanvas)for(var e=0,f=a.jqplot.CanvasManager.canvases.length;f>e;e++)if(a.jqplot.CanvasManager.free[e]===!0){d=!1,c=a.jqplot.CanvasManager.canvases[e],a.jqplot.CanvasManager.free[e]=!1,b.push(e);break}return d&&(c=document.createElement("canvas"),b.push(a.jqplot.CanvasManager.canvases.length),a.jqplot.CanvasManager.canvases.push(c),a.jqplot.CanvasManager.free.push(!1)),c},this.initCanvas=function(b){if(a.jqplot.use_excanvas)return window.G_vmlCanvasManager.initElement(b);var c=b.getContext("2d"),d=1;window.devicePixelRatio>1&&(c.webkitBackingStorePixelRatio===F||c.webkitBackingStorePixelRatio<2)&&(d=window.devicePixelRatio);var e=b.width,f=b.height;return b.width=d*b.width,b.height=d*b.height,b.style.width=e+"px",b.style.height=f+"px",c.save(),c.scale(d,d),b},this.freeAllCanvases=function(){for(var a=0,c=b.length;c>a;a++)this.freeCanvas(b[a]);b=[]},this.freeCanvas=function(b){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==F)window.G_vmlCanvasManager.uninitElement(a.jqplot.CanvasManager.canvases[b]),a.jqplot.CanvasManager.canvases[b]=null;else{var c=a.jqplot.CanvasManager.canvases[b];c.getContext("2d").clearRect(0,0,c.width,c.height),a(c).unbind().removeAttr("class").removeAttr("style"),a(c).css({left:"",top:"",position:""}),c.width=0,c.height=0,a.jqplot.CanvasManager.free[b]=!0}}},a.jqplot.log=function(){window.console&&window.console.log.apply(window.console,arguments)},a.jqplot.config={addDomReference:!1,enablePlugins:!1,defaultHeight:300,defaultWidth:400,UTCAdjust:!1,timezoneOffset:new Date(6e4*(new Date).getTimezoneOffset()),errorMessage:"",errorBackground:"",errorBorder:"",errorFontFamily:"",errorFontSize:"",errorFontStyle:"",errorFontWeight:"",catchErrors:!1,defaultTickFormatString:"%.1f",defaultColors:["#4bb2c5","#EAA228","#c5b47f","#579575","#839557","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#c747a3","#cddf54","#FBD178","#26B4E3","#bd70c7"],defaultNegativeColors:["#498991","#C08840","#9F9274","#546D61","#646C4A","#6F6621","#6E3F5F","#4F64B0","#A89050","#C45923","#187399","#945381","#959E5C","#C7AF7B","#478396","#907294"],dashLength:4,gapLength:4,dotGapLength:2.5,srcLocation:"jqplot/src/",pluginLocation:"jqplot/src/plugins/"},a.jqplot.arrayMax=function(a){return Math.max.apply(Math,a)},a.jqplot.arrayMin=function(a){return Math.min.apply(Math,a)},a.jqplot.enablePlugins=a.jqplot.config.enablePlugins,a.jqplot.support_canvas=function(){return"undefined"==typeof a.jqplot.support_canvas.result&&(a.jqplot.support_canvas.result=!!document.createElement("canvas").getContext),a.jqplot.support_canvas.result},a.jqplot.support_canvas_text=function(){return"undefined"==typeof a.jqplot.support_canvas_text.result&&(window.G_vmlCanvasManager!==F&&window.G_vmlCanvasManager._version>887?a.jqplot.support_canvas_text.result=!0:a.jqplot.support_canvas_text.result=!(!document.createElement("canvas").getContext||"function"!=typeof document.createElement("canvas").getContext("2d").fillText)),a.jqplot.support_canvas_text.result},a.jqplot.use_excanvas=a.support.boxModel&&a.support.objectAll&&$support.leadingWhitespace||a.jqplot.support_canvas()?!1:!0,a.jqplot.preInitHooks=[],a.jqplot.postInitHooks=[],a.jqplot.preParseOptionsHooks=[],a.jqplot.postParseOptionsHooks=[],a.jqplot.preDrawHooks=[],a.jqplot.postDrawHooks=[],a.jqplot.preDrawSeriesHooks=[],a.jqplot.postDrawSeriesHooks=[],a.jqplot.preDrawLegendHooks=[],a.jqplot.addLegendRowHooks=[],a.jqplot.preSeriesInitHooks=[],a.jqplot.postSeriesInitHooks=[],a.jqplot.preParseSeriesOptionsHooks=[],a.jqplot.postParseSeriesOptionsHooks=[],a.jqplot.eventListenerHooks=[],a.jqplot.preDrawSeriesShadowHooks=[],a.jqplot.postDrawSeriesShadowHooks=[],a.jqplot.ElemContainer=function(){this._elem,this._plotWidth,this._plotHeight,this._plotDimensions={height:null,width:null}},a.jqplot.ElemContainer.prototype.createElement=function(b,c,d,e,f){this._offsets=c;var g=d||"jqplot",h=document.createElement(b);return this._elem=a(h),this._elem.addClass(g),this._elem.css(e),this._elem.attr(f),h=null,this._elem},a.jqplot.ElemContainer.prototype.getWidth=function(){return this._elem?this._elem.outerWidth(!0):null},a.jqplot.ElemContainer.prototype.getHeight=function(){return this._elem?this._elem.outerHeight(!0):null},a.jqplot.ElemContainer.prototype.getPosition=function(){return this._elem?this._elem.position():{top:null,left:null,bottom:null,right:null}},a.jqplot.ElemContainer.prototype.getTop=function(){return this.getPosition().top},a.jqplot.ElemContainer.prototype.getLeft=function(){return this.getPosition().left},a.jqplot.ElemContainer.prototype.getBottom=function(){return this._elem.css("bottom")},a.jqplot.ElemContainer.prototype.getRight=function(){return this._elem.css("right")},b.prototype=new a.jqplot.ElemContainer,b.prototype.constructor=b,b.prototype.init=function(){a.isFunction(this.renderer)&&(this.renderer=new this.renderer),this.tickOptions.axis=this.name,null==this.tickOptions.showMark&&(this.tickOptions.showMark=this.showTicks),null==this.tickOptions.showMark&&(this.tickOptions.showMark=this.showTickMarks),null==this.tickOptions.showLabel&&(this.tickOptions.showLabel=this.showTicks),null==this.label||""==this.label?this.showLabel=!1:this.labelOptions.label=this.label,0==this.showLabel&&(this.labelOptions.show=!1),0==this.pad&&(this.pad=1),0==this.padMax&&(this.padMax=1),0==this.padMin&&(this.padMin=1),null==this.padMax&&(this.padMax=(this.pad-1)/2+1),null==this.padMin&&(this.padMin=(this.pad-1)/2+1),this.pad=this.padMax+this.padMin-1,(null!=this.min||null!=this.max)&&(this.autoscale=!1),null==this.syncTicks&&this.name.indexOf("y")>-1?this.syncTicks=!0:null==this.syncTicks&&(this.syncTicks=!1),this.renderer.init.call(this,this.rendererOptions)},b.prototype.draw=function(a,b){return this.__ticks&&(this.__ticks=null),this.renderer.draw.call(this,a,b)},b.prototype.set=function(){this.renderer.set.call(this)},b.prototype.pack=function(a,b){this.show&&this.renderer.pack.call(this,a,b),null==this._min&&(this._min=this.min,this._max=this.max,this._tickInterval=this.tickInterval,this._numberTicks=this.numberTicks,this.__ticks=this._ticks)},b.prototype.reset=function(){this.renderer.reset.call(this)},b.prototype.resetScale=function(b){a.extend(!0,this,{min:null,max:null,numberTicks:null,tickInterval:null,_ticks:[],ticks:[]},b),this.resetDataBounds()},b.prototype.resetDataBounds=function(){var b=this._dataBounds;b.min=null,b.max=null;for(var c,d,e,f=this.show?!0:!1,g=0;g<this._series.length;g++)if(d=this._series[g],d.show||this.scaleToHiddenSeries){e=d._plotData,"line"===d._type&&d.renderer.bands.show&&"x"!==this.name.charAt(0)&&(e=[[0,d.renderer.bands._min],[1,d.renderer.bands._max]]);var h=1,i=1;null!=d._type&&"ohlc"==d._type&&(h=3,i=2);for(var j=0,c=e.length;c>j;j++)"xaxis"==this.name||"x2axis"==this.name?((null!=e[j][0]&&e[j][0]<b.min||null==b.min)&&(b.min=e[j][0]),(null!=e[j][0]&&e[j][0]>b.max||null==b.max)&&(b.max=e[j][0])):((null!=e[j][h]&&e[j][h]<b.min||null==b.min)&&(b.min=e[j][h]),(null!=e[j][i]&&e[j][i]>b.max||null==b.max)&&(b.max=e[j][i]));f&&d.renderer.constructor!==a.jqplot.BarRenderer?f=!1:f&&this._options.hasOwnProperty("forceTickAt0")&&0==this._options.forceTickAt0?f=!1:f&&d.renderer.constructor===a.jqplot.BarRenderer&&("vertical"==d.barDirection&&"xaxis"!=this.name&&"x2axis"!=this.name?(null!=this._options.pad||null!=this._options.padMin)&&(f=!1):"horizontal"!=d.barDirection||"xaxis"!=this.name&&"x2axis"!=this.name||(null!=this._options.pad||null!=this._options.padMin)&&(f=!1))}f&&this.renderer.constructor===a.jqplot.LinearAxisRenderer&&b.min>=0&&(this.padMin=1,this.forceTickAt0=!0)},c.prototype=new a.jqplot.ElemContainer,c.prototype.constructor=c,c.prototype.setOptions=function(b){if(a.extend(!0,this,b),"inside"==this.placement&&(this.placement="insideGrid"),this.xoffset>0){if("insideGrid"==this.placement)switch(this.location){case"nw":case"w":case"sw":null==this.marginLeft&&(this.marginLeft=this.xoffset+"px"),this.marginRight="0px";break;case"ne":case"e":case"se":default:null==this.marginRight&&(this.marginRight=this.xoffset+"px"),this.marginLeft="0px"}else if("outside"==this.placement)switch(this.location){case"nw":case"w":case"sw":null==this.marginRight&&(this.marginRight=this.xoffset+"px"),this.marginLeft="0px";break;case"ne":case"e":case"se":default:null==this.marginLeft&&(this.marginLeft=this.xoffset+"px"),this.marginRight="0px"}this.xoffset=0}if(this.yoffset>0){if("outside"==this.placement)switch(this.location){case"sw":case"s":case"se":null==this.marginTop&&(this.marginTop=this.yoffset+"px"),this.marginBottom="0px";break;case"ne":case"n":case"nw":default:null==this.marginBottom&&(this.marginBottom=this.yoffset+"px"),this.marginTop="0px"}else if("insideGrid"==this.placement)switch(this.location){case"sw":case"s":case"se":null==this.marginBottom&&(this.marginBottom=this.yoffset+"px"),this.marginTop="0px";break;case"ne":case"n":case"nw":default:null==this.marginTop&&(this.marginTop=this.yoffset+"px"),this.marginBottom="0px"}this.yoffset=0}},c.prototype.init=function(){a.isFunction(this.renderer)&&(this.renderer=new this.renderer),this.renderer.init.call(this,this.rendererOptions)},c.prototype.draw=function(b,c){for(var d=0;d<a.jqplot.preDrawLegendHooks.length;d++)a.jqplot.preDrawLegendHooks[d].call(this,b);return this.renderer.draw.call(this,b,c)},c.prototype.pack=function(a){this.renderer.pack.call(this,a)},d.prototype=new a.jqplot.ElemContainer,d.prototype.constructor=d,d.prototype.init=function(){a.isFunction(this.renderer)&&(this.renderer=new this.renderer),this.renderer.init.call(this,this.rendererOptions)},d.prototype.draw=function(a){return this.renderer.draw.call(this,a)},d.prototype.pack=function(){this.renderer.pack.call(this)},e.prototype=new a.jqplot.ElemContainer,e.prototype.constructor=e,e.prototype.init=function(b,c,d){this.index=b,this.gridBorderWidth=c;var e,f,g=this.data,h=[];for(e=0,f=g.length;f>e;e++)if(this.breakOnNull)h.push(g[e]);else{if(null==g[e]||null==g[e][0]||null==g[e][1])continue;h.push(g[e])}if(this.data=h,this.color||(this.color=d.colorGenerator.get(this.index)),this.negativeColor||(this.negativeColor=d.negativeColorGenerator.get(this.index)),this.fillColor||(this.fillColor=this.color),this.fillAlpha){var i=a.jqplot.normalize2rgb(this.fillColor),i=a.jqplot.getColorComponents(i);this.fillColor="rgba("+i[0]+","+i[1]+","+i[2]+","+this.fillAlpha+")"}a.isFunction(this.renderer)&&(this.renderer=new this.renderer),this.renderer.init.call(this,this.rendererOptions,d),this.markerRenderer=new this.markerRenderer,this.markerOptions.color||(this.markerOptions.color=this.color),null==this.markerOptions.show&&(this.markerOptions.show=this.showMarker),this.showMarker=this.markerOptions.show,this.markerRenderer.init(this.markerOptions)},e.prototype.draw=function(b,c,d){var e=c==F?{}:c;b=b==F?this.canvas._ctx:b;var f,g,h;for(f=0;f<a.jqplot.preDrawSeriesHooks.length;f++)a.jqplot.preDrawSeriesHooks[f].call(this,b,e);for(this.show&&(this.renderer.setGridData.call(this,d),e.preventJqPlotSeriesDrawTrigger||a(b.canvas).trigger("jqplotSeriesDraw",[this.data,this.gridData]),g=[],g=e.data?e.data:this._stack?this._plotData:this.data,h=e.gridData||this.renderer.makeGridData.call(this,g,d),"line"===this._type&&this.renderer.smooth&&this.renderer._smoothedData.length&&(h=this.renderer._smoothedData),this.renderer.draw.call(this,b,h,e,d)),f=0;f<a.jqplot.postDrawSeriesHooks.length;f++)a.jqplot.postDrawSeriesHooks[f].call(this,b,e,d);b=c=d=f=g=h=null},e.prototype.drawShadow=function(b,c,d){var e=c==F?{}:c;b=b==F?this.shadowCanvas._ctx:b;var f,g,h;for(f=0;f<a.jqplot.preDrawSeriesShadowHooks.length;f++)a.jqplot.preDrawSeriesShadowHooks[f].call(this,b,e);for(this.shadow&&(this.renderer.setGridData.call(this,d),g=[],g=e.data?e.data:this._stack?this._plotData:this.data,h=e.gridData||this.renderer.makeGridData.call(this,g,d),this.renderer.drawShadow.call(this,b,h,e,d)),f=0;f<a.jqplot.postDrawSeriesShadowHooks.length;f++)a.jqplot.postDrawSeriesShadowHooks[f].call(this,b,e);b=c=d=f=g=h=null},e.prototype.toggleDisplay=function(a,b){var c,d;c=a.data.series?a.data.series:this,a.data.speed&&(d=a.data.speed),d?c.canvas._elem.is(":hidden")||!c.show?(c.show=!0,c.canvas._elem.removeClass("jqplot-series-hidden"),c.shadowCanvas._elem&&c.shadowCanvas._elem.fadeIn(d),c.canvas._elem.fadeIn(d,b),c.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+c.index).fadeIn(d)):(c.show=!1,c.canvas._elem.addClass("jqplot-series-hidden"),c.shadowCanvas._elem&&c.shadowCanvas._elem.fadeOut(d),c.canvas._elem.fadeOut(d,b),c.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+c.index).fadeOut(d)):c.canvas._elem.is(":hidden")||!c.show?(c.show=!0,c.canvas._elem.removeClass("jqplot-series-hidden"),c.shadowCanvas._elem&&c.shadowCanvas._elem.show(),c.canvas._elem.show(0,b),c.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+c.index).show()):(c.show=!1,c.canvas._elem.addClass("jqplot-series-hidden"),c.shadowCanvas._elem&&c.shadowCanvas._elem.hide(),c.canvas._elem.hide(0,b),c.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+c.index).hide())},f.prototype=new a.jqplot.ElemContainer,f.prototype.constructor=f,f.prototype.init=function(){a.isFunction(this.renderer)&&(this.renderer=new this.renderer),this.renderer.init.call(this,this.rendererOptions)},f.prototype.createElement=function(a,b){return this._offsets=a,this.renderer.createElement.call(this,b)},f.prototype.draw=function(){this.renderer.draw.call(this)},a.jqplot.GenericCanvas=function(){a.jqplot.ElemContainer.call(this),this._ctx},a.jqplot.GenericCanvas.prototype=new a.jqplot.ElemContainer,a.jqplot.GenericCanvas.prototype.constructor=a.jqplot.GenericCanvas,a.jqplot.GenericCanvas.prototype.createElement=function(b,c,d,e){this._offsets=b;var f="jqplot";c!=F&&(f=c);var g;return g=e.canvasManager.getCanvas(),null!=d&&(this._plotDimensions=d),g.width=this._plotDimensions.width-this._offsets.left-this._offsets.right,g.height=this._plotDimensions.height-this._offsets.top-this._offsets.bottom,this._elem=a(g),this._elem.css({position:"absolute",left:this._offsets.left,top:this._offsets.top}),this._elem.addClass(f),g=e.canvasManager.initCanvas(g),g=null,this._elem},a.jqplot.GenericCanvas.prototype.setContext=function(){return this._ctx=this._elem.get(0).getContext("2d"),this._ctx;
|
6 |
+
},a.jqplot.GenericCanvas.prototype.resetCanvas=function(){this._elem&&(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==F&&window.G_vmlCanvasManager.uninitElement(this._elem.get(0)),this._elem.emptyForce()),this._ctx=null},a.jqplot.HooksManager=function(){this.hooks=[],this.args=[]},a.jqplot.HooksManager.prototype.addOnce=function(a,b){b=b||[];for(var c=!1,d=0,e=this.hooks.length;e>d;d++)this.hooks[d]==a&&(c=!0);c||(this.hooks.push(a),this.args.push(b))},a.jqplot.HooksManager.prototype.add=function(a,b){b=b||[],this.hooks.push(a),this.args.push(b)},a.jqplot.EventListenerManager=function(){this.hooks=[]},a.jqplot.EventListenerManager.prototype.addOnce=function(a,b){for(var c,d,e=!1,d=0,f=this.hooks.length;f>d;d++)c=this.hooks[d],c[0]==a&&c[1]==b&&(e=!0);e||this.hooks.push([a,b])},a.jqplot.EventListenerManager.prototype.add=function(a,b){this.hooks.push([a,b])};var G=["yMidAxis","xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];a.jqplot.computeHighlightColors=function(b){var c;if(a.isArray(b)){c=[];for(var d=0;d<b.length;d++){for(var e=a.jqplot.getColorComponents(b[d]),f=[e[0],e[1],e[2]],g=f[0]+f[1]+f[2],h=0;3>h;h++)f[h]=g>660?.85*f[h]:.73*f[h]+90,f[h]=parseInt(f[h],10),f[h]>255?255:f[h];f[3]=.3+.35*e[3],c.push("rgba("+f[0]+","+f[1]+","+f[2]+","+f[3]+")")}}else{for(var e=a.jqplot.getColorComponents(b),f=[e[0],e[1],e[2]],g=f[0]+f[1]+f[2],h=0;3>h;h++)f[h]=g>660?.85*f[h]:.73*f[h]+90,f[h]=parseInt(f[h],10),f[h]>255?255:f[h];f[3]=.3+.35*e[3],c="rgba("+f[0]+","+f[1]+","+f[2]+","+f[3]+")"}return c},a.jqplot.ColorGenerator=function(b){b=b||a.jqplot.config.defaultColors;var c=0;this.next=function(){return c<b.length?b[c++]:(c=0,b[c++])},this.previous=function(){return c>0?b[c--]:(c=b.length-1,b[c])},this.get=function(a){var c=a-b.length*Math.floor(a/b.length);return b[c]},this.setColors=function(a){b=a},this.reset=function(){c=0},this.getIndex=function(){return c},this.setIndex=function(a){c=a}},a.jqplot.hex2rgb=function(a,b){a=a.replace("#",""),3==a.length&&(a=a.charAt(0)+a.charAt(0)+a.charAt(1)+a.charAt(1)+a.charAt(2)+a.charAt(2));var c;return c="rgba("+parseInt(a.slice(0,2),16)+", "+parseInt(a.slice(2,4),16)+", "+parseInt(a.slice(4,6),16),b&&(c+=", "+b),c+=")"},a.jqplot.rgb2hex=function(a){for(var b=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/,c=a.match(b),d="#",e=1;4>e;e++){var f;-1!=c[e].search(/%/)?(f=parseInt(255*c[e]/100,10).toString(16),1==f.length&&(f="0"+f)):(f=parseInt(c[e],10).toString(16),1==f.length&&(f="0"+f)),d+=f}return d},a.jqplot.normalize2rgb=function(b,c){if(-1!=b.search(/^ *rgba?\(/))return b;if(-1!=b.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/))return a.jqplot.hex2rgb(b,c);throw new Error("Invalid color spec")},a.jqplot.getColorComponents=function(b){b=a.jqplot.colorKeywordMap[b]||b;for(var c=a.jqplot.normalize2rgb(b),d=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/,e=c.match(d),f=[],g=1;4>g;g++)-1!=e[g].search(/%/)?f[g-1]=parseInt(255*e[g]/100,10):f[g-1]=parseInt(e[g],10);return f[3]=parseFloat(e[4])?parseFloat(e[4]):1,f},a.jqplot.colorKeywordMap={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb( 0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb( 0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb( 0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb( 95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(220, 20, 60)",cyan:"rgb( 0, 255, 255)",darkblue:"rgb( 0, 0, 139)",darkcyan:"rgb( 0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgreen:"rgb( 0, 100, 0)",darkgrey:"rgb(169, 169, 169)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb( 85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb( 72, 61, 139)",darkslategray:"rgb( 47, 79, 79)",darkslategrey:"rgb( 47, 79, 79)",darkturquoise:"rgb( 0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb( 0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb( 30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb( 34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb( 0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb( 75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgray:"rgb(211, 211, 211)",lightgreen:"rgb(144, 238, 144)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb( 32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb( 0, 255, 0)",limegreen:"rgb( 50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb( 0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb( 60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb( 0, 250, 154)",mediumturquoise:"rgb( 72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb( 25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb( 0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb( 65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb( 46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb( 0, 255, 127)",steelblue:"rgb( 70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb( 0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb( 64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)"},a.jqplot.AxisLabelRenderer=function(b){a.jqplot.ElemContainer.call(this),this.axis,this.show=!0,this.label="",this.fontFamily=null,this.fontSize=null,this.textColor=null,this._elem,this.escapeHTML=!1,a.extend(!0,this,b)},a.jqplot.AxisLabelRenderer.prototype=new a.jqplot.ElemContainer,a.jqplot.AxisLabelRenderer.prototype.constructor=a.jqplot.AxisLabelRenderer,a.jqplot.AxisLabelRenderer.prototype.init=function(b){a.extend(!0,this,b)},a.jqplot.AxisLabelRenderer.prototype.draw=function(b,c){return this._elem&&(this._elem.emptyForce(),this._elem=null),this._elem=a('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>'),Number(this.label)&&this._elem.css("white-space","nowrap"),this.escapeHTML?this._elem.text(this.label):this._elem.html(this.label),this.fontFamily&&this._elem.css("font-family",this.fontFamily),this.fontSize&&this._elem.css("font-size",this.fontSize),this.textColor&&this._elem.css("color",this.textColor),this._elem},a.jqplot.AxisLabelRenderer.prototype.pack=function(){},a.jqplot.AxisTickRenderer=function(b){a.jqplot.ElemContainer.call(this),this.mark="outside",this.axis,this.showMark=!0,this.showGridline=!0,this.isMinorTick=!1,this.size=4,this.markSize=6,this.show=!0,this.showLabel=!0,this.label=null,this.value=null,this._styles={},this.formatter=a.jqplot.DefaultTickFormatter,this.prefix="",this.suffix="",this.formatString="",this.fontFamily,this.fontSize,this.textColor,this.escapeHTML=!1,this._elem,this._breakTick=!1,a.extend(!0,this,b)},a.jqplot.AxisTickRenderer.prototype.init=function(b){a.extend(!0,this,b)},a.jqplot.AxisTickRenderer.prototype=new a.jqplot.ElemContainer,a.jqplot.AxisTickRenderer.prototype.constructor=a.jqplot.AxisTickRenderer,a.jqplot.AxisTickRenderer.prototype.setTick=function(a,b,c){return this.value=a,this.axis=b,c&&(this.isMinorTick=!0),this},a.jqplot.AxisTickRenderer.prototype.draw=function(){null===this.label&&(this.label=this.prefix+this.formatter(this.formatString,this.value)+this.suffix);var b={position:"absolute"};Number(this.label)&&(b.whitSpace="nowrap"),this._elem&&(this._elem.emptyForce(),this._elem=null),this._elem=a(document.createElement("div")),this._elem.addClass("jqplot-"+this.axis+"-tick"),this.escapeHTML?this._elem.text(this.label):this._elem.html(this.label),this._elem.css(b);for(var c in this._styles)this._elem.css(c,this._styles[c]);return this.fontFamily&&this._elem.css("font-family",this.fontFamily),this.fontSize&&this._elem.css("font-size",this.fontSize),this.textColor&&this._elem.css("color",this.textColor),this._breakTick&&this._elem.addClass("jqplot-breakTick"),this._elem},a.jqplot.DefaultTickFormatter=function(b,c){return"number"==typeof c?(b||(b=a.jqplot.config.defaultTickFormatString),a.jqplot.sprintf(b,c)):String(c)},a.jqplot.PercentTickFormatter=function(b,c){return"number"==typeof c?(c=100*c,b||(b=a.jqplot.config.defaultTickFormatString),a.jqplot.sprintf(b,c)):String(c)},a.jqplot.AxisTickRenderer.prototype.pack=function(){},a.jqplot.CanvasGridRenderer=function(){this.shadowRenderer=new a.jqplot.ShadowRenderer},a.jqplot.CanvasGridRenderer.prototype.init=function(b){this._ctx,a.extend(!0,this,b);var c={lineJoin:"miter",lineCap:"round",fill:!1,isarc:!1,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:!1,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(c)},a.jqplot.CanvasGridRenderer.prototype.createElement=function(b){var c;this._elem&&(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==F&&(c=this._elem.get(0),window.G_vmlCanvasManager.uninitElement(c),c=null),this._elem.emptyForce(),this._elem=null),c=b.canvasManager.getCanvas();var d=this._plotDimensions.width,e=this._plotDimensions.height;return c.width=d,c.height=e,this._elem=a(c),this._elem.addClass("jqplot-grid-canvas"),this._elem.css({position:"absolute",left:0,top:0}),c=b.canvasManager.initCanvas(c),this._top=this._offsets.top,this._bottom=e-this._offsets.bottom,this._left=this._offsets.left,this._right=d-this._offsets.right,this._width=this._right-this._left,this._height=this._bottom-this._top,c=null,this._elem},a.jqplot.CanvasGridRenderer.prototype.draw=function(){function b(b,d,e,f,g){c.save(),g=g||{},(null==g.lineWidth||0!=g.lineWidth)&&(a.extend(!0,c,g),c.beginPath(),c.moveTo(b,d),c.lineTo(e,f),c.stroke(),c.restore())}this._ctx=this._elem.get(0).getContext("2d");var c=this._ctx,d=this._axes;c.save(),c.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height),c.fillStyle=this.backgroundColor||this.background,c.fillRect(this._left,this._top,this._width,this._height),c.save(),c.lineJoin="miter",c.lineCap="butt",c.lineWidth=this.gridLineWidth,c.strokeStyle=this.gridLineColor;for(var e,f,g,h,i=["xaxis","yaxis","x2axis","y2axis"],j=4;j>0;j--){var k=i[j-1],l=d[k],m=l._ticks,n=m.length;if(l.show){if(l.drawBaseline){var o={};switch(null!==l.baselineWidth&&(o.lineWidth=l.baselineWidth),null!==l.baselineColor&&(o.strokeStyle=l.baselineColor),k){case"xaxis":b(this._left,this._bottom,this._right,this._bottom,o);break;case"yaxis":b(this._left,this._bottom,this._left,this._top,o);break;case"x2axis":b(this._left,this._bottom,this._right,this._bottom,o);break;case"y2axis":b(this._right,this._bottom,this._right,this._top,o)}}for(var p=n;p>0;p--){var q=m[p-1];if(q.show){var r=Math.round(l.u2p(q.value))+.5;switch(k){case"xaxis":if(q.showGridline&&this.drawGridlines&&(!q.isMinorTick&&l.drawMajorGridlines||q.isMinorTick&&l.drawMinorGridlines)&&b(r,this._top,r,this._bottom),q.showMark&&q.mark&&(!q.isMinorTick&&l.drawMajorTickMarks||q.isMinorTick&&l.drawMinorTickMarks)){g=q.markSize,h=q.mark;var r=Math.round(l.u2p(q.value))+.5;switch(h){case"outside":e=this._bottom,f=this._bottom+g;break;case"inside":e=this._bottom-g,f=this._bottom;break;case"cross":e=this._bottom-g,f=this._bottom+g;break;default:e=this._bottom,f=this._bottom+g}this.shadow&&this.renderer.shadowRenderer.draw(c,[[r,e],[r,f]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:.75*this.gridLineWidth,depth:2,fill:!1,closePath:!1}),b(r,e,r,f)}break;case"yaxis":if(q.showGridline&&this.drawGridlines&&(!q.isMinorTick&&l.drawMajorGridlines||q.isMinorTick&&l.drawMinorGridlines)&&b(this._right,r,this._left,r),q.showMark&&q.mark&&(!q.isMinorTick&&l.drawMajorTickMarks||q.isMinorTick&&l.drawMinorTickMarks)){g=q.markSize,h=q.mark;var r=Math.round(l.u2p(q.value))+.5;switch(h){case"outside":e=this._left-g,f=this._left;break;case"inside":e=this._left,f=this._left+g;break;case"cross":e=this._left-g,f=this._left+g;break;default:e=this._left-g,f=this._left}this.shadow&&this.renderer.shadowRenderer.draw(c,[[e,r],[f,r]],{lineCap:"butt",lineWidth:1.5*this.gridLineWidth,offset:.75*this.gridLineWidth,fill:!1,closePath:!1}),b(e,r,f,r,{strokeStyle:l.borderColor})}break;case"x2axis":if(q.showGridline&&this.drawGridlines&&(!q.isMinorTick&&l.drawMajorGridlines||q.isMinorTick&&l.drawMinorGridlines)&&b(r,this._bottom,r,this._top),q.showMark&&q.mark&&(!q.isMinorTick&&l.drawMajorTickMarks||q.isMinorTick&&l.drawMinorTickMarks)){g=q.markSize,h=q.mark;var r=Math.round(l.u2p(q.value))+.5;switch(h){case"outside":e=this._top-g,f=this._top;break;case"inside":e=this._top,f=this._top+g;break;case"cross":e=this._top-g,f=this._top+g;break;default:e=this._top-g,f=this._top}this.shadow&&this.renderer.shadowRenderer.draw(c,[[r,e],[r,f]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:.75*this.gridLineWidth,depth:2,fill:!1,closePath:!1}),b(r,e,r,f)}break;case"y2axis":if(q.showGridline&&this.drawGridlines&&(!q.isMinorTick&&l.drawMajorGridlines||q.isMinorTick&&l.drawMinorGridlines)&&b(this._left,r,this._right,r),q.showMark&&q.mark&&(!q.isMinorTick&&l.drawMajorTickMarks||q.isMinorTick&&l.drawMinorTickMarks)){g=q.markSize,h=q.mark;var r=Math.round(l.u2p(q.value))+.5;switch(h){case"outside":e=this._right,f=this._right+g;break;case"inside":e=this._right-g,f=this._right;break;case"cross":e=this._right-g,f=this._right+g;break;default:e=this._right,f=this._right+g}this.shadow&&this.renderer.shadowRenderer.draw(c,[[e,r],[f,r]],{lineCap:"butt",lineWidth:1.5*this.gridLineWidth,offset:.75*this.gridLineWidth,fill:!1,closePath:!1}),b(e,r,f,r,{strokeStyle:l.borderColor})}}}}q=null}l=null,m=null}i=["y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];for(var j=7;j>0;j--){var l=d[i[j-1]],m=l._ticks;if(l.show){var s=m[l.numberTicks-1],t=m[0],u=l.getLeft(),v=[[u,s.getTop()+s.getHeight()/2],[u,t.getTop()+t.getHeight()/2+1]];this.shadow&&this.renderer.shadowRenderer.draw(c,v,{lineCap:"butt",fill:!1,closePath:!1}),b(v[0][0],v[0][1],v[1][0],v[1][1],{lineCap:"butt",strokeStyle:l.borderColor,lineWidth:l.borderWidth});for(var p=m.length;p>0;p--){var q=m[p-1];g=q.markSize,h=q.mark;var r=Math.round(l.u2p(q.value))+.5;if(q.showMark&&q.mark){switch(h){case"outside":e=u,f=u+g;break;case"inside":e=u-g,f=u;break;case"cross":e=u-g,f=u+g;break;default:e=u,f=u+g}v=[[e,r],[f,r]],this.shadow&&this.renderer.shadowRenderer.draw(c,v,{lineCap:"butt",lineWidth:1.5*this.gridLineWidth,offset:.75*this.gridLineWidth,fill:!1,closePath:!1}),b(e,r,f,r,{strokeStyle:l.borderColor})}q=null}t=null}l=null,m=null}if(c.restore(),this.shadow){var v=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(c,v)}0!=this.borderWidth&&this.drawBorder&&(b(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:d.x2axis.borderColor,lineWidth:d.x2axis.borderWidth}),b(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:d.y2axis.borderColor,lineWidth:d.y2axis.borderWidth}),b(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:d.xaxis.borderColor,lineWidth:d.xaxis.borderWidth}),b(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:d.yaxis.borderColor,lineWidth:d.yaxis.borderWidth})),c.restore(),c=null,d=null},a.jqplot.DivTitleRenderer=function(){},a.jqplot.DivTitleRenderer.prototype.init=function(b){a.extend(!0,this,b)},a.jqplot.DivTitleRenderer.prototype.draw=function(){this._elem&&(this._elem.emptyForce(),this._elem=null);var b=(this.renderer,document.createElement("div"));if(this._elem=a(b),this._elem.addClass("jqplot-title"),this.text){if(this.text){var c;this.color?c=this.color:this.textColor&&(c=this.textColor);var d={position:"absolute",top:"0px",left:"0px"};this._plotWidth&&(d.width=this._plotWidth+"px"),this.fontSize&&(d.fontSize=this.fontSize),"string"==typeof this.textAlign?d.textAlign=this.textAlign:d.textAlign="center",c&&(d.color=c),this.paddingBottom&&(d.paddingBottom=this.paddingBottom),this.fontFamily&&(d.fontFamily=this.fontFamily),this._elem.css(d),this.escapeHtml?this._elem.text(this.text):this._elem.html(this.text)}}else this.show=!1,this._elem.height(0),this._elem.width(0);return b=null,this._elem},a.jqplot.DivTitleRenderer.prototype.pack=function(){};var H=.1;a.jqplot.LinePattern=function(b,c){var d={dotted:[H,a.jqplot.config.dotGapLength],dashed:[a.jqplot.config.dashLength,a.jqplot.config.gapLength],solid:null};if("string"==typeof c)if("."===c[0]||"-"===c[0]){var e=c;c=[];for(var f=0,g=e.length;g>f;f++){if("."===e[f])c.push(H);else{if("-"!==e[f])continue;c.push(a.jqplot.config.dashLength)}c.push(a.jqplot.config.gapLength)}}else c=d[c];if(!c||!c.length)return b;var h=0,i=c[0],j=0,k=0,l=0,m=0,n=function(a,c){b.moveTo(a,c),j=a,k=c,l=a,m=c},o=function(a,d){var e=b.lineWidth,f=a-j,g=d-k,l=Math.sqrt(f*f+g*g);if(l>0&&e>0)for(f/=l,g/=l;;){var m=e*i;if(!(l>m)){j=a,k=d,0==(1&h)?b.lineTo(j,k):b.moveTo(j,k),i-=l/e;break}j+=m*f,k+=m*g,0==(1&h)?b.lineTo(j,k):b.moveTo(j,k),l-=m,h++,h>=c.length&&(h=0),i=c[h]}},p=function(){b.beginPath()},q=function(){o(l,m)};return{moveTo:n,lineTo:o,beginPath:p,closePath:q}},a.jqplot.LineRenderer=function(){this.shapeRenderer=new a.jqplot.ShapeRenderer,this.shadowRenderer=new a.jqplot.ShadowRenderer},a.jqplot.LineRenderer.prototype.init=function(b,c){b=b||{},this._type="line",this.renderer.animation={show:!1,direction:"left",speed:2500,_supported:!0},this.renderer.smooth=!1,this.renderer.tension=null,this.renderer.constrainSmoothing=!0,this.renderer._smoothedData=[],this.renderer._smoothedPlotData=[],this.renderer._hiBandGridData=[],this.renderer._lowBandGridData=[],this.renderer._hiBandSmoothedData=[],this.renderer._lowBandSmoothedData=[],this.renderer.bandData=[],this.renderer.bands={show:!1,hiData:[],lowData:[],color:this.color,showLines:!1,fill:!0,fillColor:null,_min:null,_max:null,interval:"3%"};var d={highlightMouseOver:b.highlightMouseOver,highlightMouseDown:b.highlightMouseDown,highlightColor:b.highlightColor};delete b.highlightMouseOver,delete b.highlightMouseDown,delete b.highlightColor,a.extend(!0,this.renderer,b),this.renderer.options=b,this.renderer.bandData.length>1&&(!b.bands||null==b.bands.show)?this.renderer.bands.show=!0:b.bands&&null==b.bands.show&&null!=b.bands.interval&&(this.renderer.bands.show=!0),this.fill&&(this.renderer.bands.show=!1),this.renderer.bands.show&&this.renderer.initBands.call(this,this.renderer.options,c),this._stack&&(this.renderer.smooth=!1);var e={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:!1,strokeStyle:this.color,fillStyle:this.fillColor,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shapeRenderer.init(e);var f=b.shadowOffset;null==f&&(f=this.lineWidth>2.5?1.25*(1+.6*(Math.atan(this.lineWidth/2.5)/.785398163-1)):1.25*Math.atan(this.lineWidth/2.5)/.785398163);var g={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:!1,angle:this.shadowAngle,offset:f,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};if(this.renderer.shadowRenderer.init(g),this._areaPoints=[],this._boundingBox=[[],[]],!this.isTrendline&&this.fill||this.renderer.bands.show){if(this.highlightMouseOver=!0,this.highlightMouseDown=!1,this.highlightColor=null,d.highlightMouseDown&&null==d.highlightMouseOver&&(d.highlightMouseOver=!1),a.extend(!0,this,{highlightMouseOver:d.highlightMouseOver,highlightMouseDown:d.highlightMouseDown,highlightColor:d.highlightColor}),!this.highlightColor){var h=this.renderer.bands.show?this.renderer.bands.fillColor:this.fillColor;this.highlightColor=a.jqplot.computeHighlightColors(h)}this.highlighter&&(this.highlighter.show=!1)}!this.isTrendline&&c&&(c.plugins.lineRenderer={},c.postInitHooks.addOnce(l),c.postDrawHooks.addOnce(m),c.eventListenerHooks.addOnce("jqplotMouseMove",p),c.eventListenerHooks.addOnce("jqplotMouseDown",q),c.eventListenerHooks.addOnce("jqplotMouseUp",r),c.eventListenerHooks.addOnce("jqplotClick",s),c.eventListenerHooks.addOnce("jqplotRightClick",t))},a.jqplot.LineRenderer.prototype.initBands=function(b,c){var d=b.bandData||[],e=this.renderer.bands;e.hiData=[],e.lowData=[];var f=this.data;if(e._max=null,e._min=null,2==d.length)if(a.isArray(d[0][0])){for(var g,h=0,i=0,j=0,k=d[0].length;k>j;j++)g=d[0][j],(null!=g[1]&&g[1]>e._max||null==e._max)&&(e._max=g[1]),(null!=g[1]&&g[1]<e._min||null==e._min)&&(e._min=g[1]);for(var j=0,k=d[1].length;k>j;j++)g=d[1][j],(null!=g[1]&&g[1]>e._max||null==e._max)&&(e._max=g[1],i=1),(null!=g[1]&&g[1]<e._min||null==e._min)&&(e._min=g[1],h=1);i===h&&(e.show=!1),e.hiData=d[i],e.lowData=d[h]}else if(d[0].length===f.length&&d[1].length===f.length)for(var l=d[0][0]>d[1][0]?0:1,m=l?0:1,j=0,k=f.length;k>j;j++)e.hiData.push([f[j][0],d[l][j]]),e.lowData.push([f[j][0],d[m][j]]);else e.show=!1;else if(d.length>2&&!a.isArray(d[0][0]))for(var l=d[0][0]>d[0][1]?0:1,m=l?0:1,j=0,k=d.length;k>j;j++)e.hiData.push([f[j][0],d[j][l]]),e.lowData.push([f[j][0],d[j][m]]);else{var n=e.interval,o=null,p=null,q=null,r=null;if(a.isArray(n)?(o=n[0],p=n[1]):o=n,isNaN(o)?"%"===o.charAt(o.length-1)&&(q="multiply",o=parseFloat(o)/100+1):(o=parseFloat(o),q="add"),null!==p&&isNaN(p)?"%"===p.charAt(p.length-1)&&(r="multiply",p=parseFloat(p)/100+1):null!==p&&(p=parseFloat(p),r="add"),null!==o){if(null===p&&(p=-o,r=q,"multiply"===r&&(p+=2)),p>o){var s=o;o=p,p=s,s=q,q=r,r=s}for(var j=0,k=f.length;k>j;j++){switch(q){case"add":e.hiData.push([f[j][0],f[j][1]+o]);break;case"multiply":e.hiData.push([f[j][0],f[j][1]*o])}switch(r){case"add":e.lowData.push([f[j][0],f[j][1]+p]);break;case"multiply":e.lowData.push([f[j][0],f[j][1]*p])}}}else e.show=!1}for(var t=e.hiData,u=e.lowData,j=0,k=t.length;k>j;j++)(null!=t[j][1]&&t[j][1]>e._max||null==e._max)&&(e._max=t[j][1]);for(var j=0,k=u.length;k>j;j++)(null!=u[j][1]&&u[j][1]<e._min||null==e._min)&&(e._min=u[j][1]);if(null===e.fillColor){var v=a.jqplot.getColorComponents(e.color);v[3]=.5*v[3],e.fillColor="rgba("+v[0]+", "+v[1]+", "+v[2]+", "+v[3]+")"}},a.jqplot.LineRenderer.prototype.setGridData=function(a){var b=this._xaxis.series_u2p,c=this._yaxis.series_u2p,d=this._plotData,e=this._prevPlotData;this.gridData=[],this._prevGridData=[],this.renderer._smoothedData=[],this.renderer._smoothedPlotData=[],this.renderer._hiBandGridData=[],this.renderer._lowBandGridData=[],this.renderer._hiBandSmoothedData=[],this.renderer._lowBandSmoothedData=[];for(var f=this.renderer.bands,g=!1,h=0,i=d.length;i>h;h++)null!=d[h][0]&&null!=d[h][1]?this.gridData.push([b.call(this._xaxis,d[h][0]),c.call(this._yaxis,d[h][1])]):null==d[h][0]?(g=!0,this.gridData.push([null,c.call(this._yaxis,d[h][1])])):null==d[h][1]&&(g=!0,this.gridData.push([b.call(this._xaxis,d[h][0]),null])),null!=e[h]&&null!=e[h][0]&&null!=e[h][1]?this._prevGridData.push([b.call(this._xaxis,e[h][0]),c.call(this._yaxis,e[h][1])]):null!=e[h]&&null==e[h][0]?this._prevGridData.push([null,c.call(this._yaxis,e[h][1])]):null!=e[h]&&null!=e[h][0]&&null==e[h][1]&&this._prevGridData.push([b.call(this._xaxis,e[h][0]),null]);if(g&&(this.renderer.smooth=!1,"line"===this._type&&(f.show=!1)),"line"===this._type&&f.show){for(var h=0,i=f.hiData.length;i>h;h++)this.renderer._hiBandGridData.push([b.call(this._xaxis,f.hiData[h][0]),c.call(this._yaxis,f.hiData[h][1])]);for(var h=0,i=f.lowData.length;i>h;h++)this.renderer._lowBandGridData.push([b.call(this._xaxis,f.lowData[h][0]),c.call(this._yaxis,f.lowData[h][1])])}if("line"===this._type&&this.renderer.smooth&&this.gridData.length>2){var l;this.renderer.constrainSmoothing?(l=j.call(this,this.gridData),this.renderer._smoothedData=l[0],this.renderer._smoothedPlotData=l[1],f.show&&(l=j.call(this,this.renderer._hiBandGridData),this.renderer._hiBandSmoothedData=l[0],l=j.call(this,this.renderer._lowBandGridData),this.renderer._lowBandSmoothedData=l[0]),l=null):(l=k.call(this,this.gridData),this.renderer._smoothedData=l[0],this.renderer._smoothedPlotData=l[1],f.show&&(l=k.call(this,this.renderer._hiBandGridData),this.renderer._hiBandSmoothedData=l[0],l=k.call(this,this.renderer._lowBandGridData),this.renderer._lowBandSmoothedData=l[0]),l=null)}},a.jqplot.LineRenderer.prototype.makeGridData=function(a,b){var c=this._xaxis.series_u2p,d=this._yaxis.series_u2p,e=[];this.renderer._smoothedData=[],this.renderer._smoothedPlotData=[],this.renderer._hiBandGridData=[],this.renderer._lowBandGridData=[],this.renderer._hiBandSmoothedData=[],this.renderer._lowBandSmoothedData=[];for(var f=this.renderer.bands,g=!1,h=0;h<a.length;h++)null!=a[h][0]&&null!=a[h][1]?(this.step&&h>0&&e.push([c.call(this._xaxis,a[h][0]),d.call(this._yaxis,a[h-1][1])]),e.push([c.call(this._xaxis,a[h][0]),d.call(this._yaxis,a[h][1])])):null==a[h][0]?(g=!0,e.push([null,d.call(this._yaxis,a[h][1])])):null==a[h][1]&&(g=!0,e.push([c.call(this._xaxis,a[h][0]),null]));if(g&&(this.renderer.smooth=!1,"line"===this._type&&(f.show=!1)),"line"===this._type&&f.show){for(var h=0,i=f.hiData.length;i>h;h++)this.renderer._hiBandGridData.push([c.call(this._xaxis,f.hiData[h][0]),d.call(this._yaxis,f.hiData[h][1])]);for(var h=0,i=f.lowData.length;i>h;h++)this.renderer._lowBandGridData.push([c.call(this._xaxis,f.lowData[h][0]),d.call(this._yaxis,f.lowData[h][1])])}if("line"===this._type&&this.renderer.smooth&&e.length>2){var l;this.renderer.constrainSmoothing?(l=j.call(this,e),this.renderer._smoothedData=l[0],this.renderer._smoothedPlotData=l[1],f.show&&(l=j.call(this,this.renderer._hiBandGridData),this.renderer._hiBandSmoothedData=l[0],l=j.call(this,this.renderer._lowBandGridData),this.renderer._lowBandSmoothedData=l[0]),l=null):(l=k.call(this,e),this.renderer._smoothedData=l[0],this.renderer._smoothedPlotData=l[1],f.show&&(l=k.call(this,this.renderer._hiBandGridData),this.renderer._hiBandSmoothedData=l[0],l=k.call(this,this.renderer._lowBandGridData),this.renderer._lowBandSmoothedData=l[0]),l=null)}return e},a.jqplot.LineRenderer.prototype.draw=function(b,c,d,e){var f,g,h,i,j,k=a.extend(!0,{},d),l=k.shadow!=F?k.shadow:this.shadow,m=k.showLine!=F?k.showLine:this.showLine,n=k.fill!=F?k.fill:this.fill,o=k.fillAndStroke!=F?k.fillAndStroke:this.fillAndStroke;if(b.save(),c.length){if(m)if(n){if(this.fillToZero){var p=this.negativeColor;this.useNegativeColors||(p=k.fillStyle);var q=!1,r=k.fillStyle;if(o)var s=c.slice(0);if(0!=this.index&&this._stack){for(var t=this._prevGridData,f=t.length;f>0;f--)c.push(t[f-1]);l&&this.renderer.shadowRenderer.draw(b,c,k),this._areaPoints=c,this.renderer.shapeRenderer.draw(b,c,k)}else{var u=[],v=this.renderer.smooth?this.renderer._smoothedPlotData:this._plotData;this._areaPoints=[];var w=this._yaxis.series_u2p(this.fillToValue);this._xaxis.series_u2p(this.fillToValue);if(k.closePath=!0,"y"==this.fillAxis){u.push([c[0][0],w]),this._areaPoints.push([c[0][0],w]);for(var f=0;f<c.length-1;f++)if(u.push(c[f]),this._areaPoints.push(c[f]),v[f][1]*v[f+1][1]<=0){v[f][1]<0?(q=!0,k.fillStyle=p):(q=!1,k.fillStyle=r);var x=c[f][0]+(c[f+1][0]-c[f][0])*(w-c[f][1])/(c[f+1][1]-c[f][1]);u.push([x,w]),this._areaPoints.push([x,w]),l&&this.renderer.shadowRenderer.draw(b,u,k),this.renderer.shapeRenderer.draw(b,u,k),u=[[x,w]]}v[c.length-1][1]<0?(q=!0,k.fillStyle=p):(q=!1,k.fillStyle=r),u.push(c[c.length-1]),this._areaPoints.push(c[c.length-1]),u.push([c[c.length-1][0],w]),this._areaPoints.push([c[c.length-1][0],w])}l&&this.renderer.shadowRenderer.draw(b,u,k),this.renderer.shapeRenderer.draw(b,u,k)}}else{if(o)var s=c.slice(0);if(0!=this.index&&this._stack)for(var t=this._prevGridData,f=t.length;f>0;f--)c.push(t[f-1]);else{var y=b.canvas.height;c.unshift([c[0][0],y]);var z=c.length;c.push([c[z-1][0],y])}this._areaPoints=c,l&&this.renderer.shadowRenderer.draw(b,c,k),this.renderer.shapeRenderer.draw(b,c,k)}if(o){var A=a.extend(!0,{},k,{fill:!1,closePath:!1});if(this.renderer.shapeRenderer.draw(b,s,A),this.markerRenderer.show)for(this.renderer.smooth&&(s=this.gridData),f=0;f<s.length;f++)this.markerRenderer.draw(s[f][0],s[f][1],b,k.markerOptions)}}else{if(this.renderer.bands.show){var B,C=a.extend(!0,{},k);this.renderer.bands.showLines&&(B=this.renderer.smooth?this.renderer._hiBandSmoothedData:this.renderer._hiBandGridData,this.renderer.shapeRenderer.draw(b,B,k),B=this.renderer.smooth?this.renderer._lowBandSmoothedData:this.renderer._lowBandGridData,this.renderer.shapeRenderer.draw(b,B,C)),this.renderer.bands.fill&&(B=this.renderer.smooth?this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse()):this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse()),this._areaPoints=B,C.closePath=!0,C.fill=!0,C.fillStyle=this.renderer.bands.fillColor,this.renderer.shapeRenderer.draw(b,B,C))}l&&this.renderer.shadowRenderer.draw(b,c,k),this.renderer.shapeRenderer.draw(b,c,k)}var g=i=h=j=null;for(f=0;f<this._areaPoints.length;f++){var D=this._areaPoints[f];(g>D[0]||null==g)&&(g=D[0]),(j<D[1]||null==j)&&(j=D[1]),(i<D[0]||null==i)&&(i=D[0]),(h>D[1]||null==h)&&(h=D[1])}if("line"===this.type&&this.renderer.bands.show&&(j=this._yaxis.series_u2p(this.renderer.bands._min),h=this._yaxis.series_u2p(this.renderer.bands._max)),this._boundingBox=[[g,j],[i,h]],this.markerRenderer.show&&!n)for(this.renderer.smooth&&(c=this.gridData),f=0;f<c.length;f++)null!=c[f][0]&&null!=c[f][1]&&this.markerRenderer.draw(c[f][0],c[f][1],b,k.markerOptions)}b.restore()},a.jqplot.LineRenderer.prototype.drawShadow=function(a,b,c){},a.jqplot.LinearAxisRenderer=function(){},a.jqplot.LinearAxisRenderer.prototype.init=function(b){this.breakPoints=null,this.breakTickLabel="≈",this.drawBaseline=!0,this.baselineWidth=null,this.baselineColor=null,this.forceTickAt0=!1,this.forceTickAt100=!1,this.tickInset=0,this.minorTicks=0,this.alignTicks=!1,this._autoFormatString="",this._overrideFormatString=!1,this._scalefact=1,a.extend(!0,this,b),this.breakPoints&&(a.isArray(this.breakPoints)?(this.breakPoints.length<2||this.breakPoints[1]<=this.breakPoints[0])&&(this.breakPoints=null):this.breakPoints=null),
|
7 |
+
null!=this.numberTicks&&this.numberTicks<2&&(this.numberTicks=2),this.resetDataBounds()},a.jqplot.LinearAxisRenderer.prototype.draw=function(b,c){if(this.show){this.renderer.createTicks.call(this,c);if(this._elem&&(this._elem.emptyForce(),this._elem=null),this._elem=a(document.createElement("div")),this._elem.addClass("jqplot-axis jqplot-"+this.name),this._elem.css("position","absolute"),"xaxis"==this.name||"x2axis"==this.name?this._elem.width(this._plotDimensions.width):this._elem.height(this._plotDimensions.height),this.labelOptions.axis=this.name,this._label=new this.labelRenderer(this.labelOptions),this._label.show){var d=this._label.draw(b,c);d.appendTo(this._elem),d=null}for(var e,f=this._ticks,g=0;g<f.length;g++)e=f[g],e.show&&e.showLabel&&(!e.isMinorTick||this.showMinorTicks)&&this._elem.append(e.draw(b,c));e=null,f=null}return this._elem},a.jqplot.LinearAxisRenderer.prototype.reset=function(){this.min=this._options.min,this.max=this._options.max,this.tickInterval=this._options.tickInterval,this.numberTicks=this._options.numberTicks,this._autoFormatString="",this._overrideFormatString&&this.tickOptions&&this.tickOptions.formatString&&(this.tickOptions.formatString="")},a.jqplot.LinearAxisRenderer.prototype.set=function(){var b,c=0,d=0,e=0,f=null==this._label?!1:this._label.show;if(this.show){for(var g,h=this._ticks,i=0;i<h.length;i++)g=h[i],g._breakTick||!g.show||!g.showLabel||g.isMinorTick&&!this.showMinorTicks||(b="xaxis"==this.name||"x2axis"==this.name?g._elem.outerHeight(!0):g._elem.outerWidth(!0),b>c&&(c=b));g=null,h=null,f&&(d=this._label._elem.outerWidth(!0),e=this._label._elem.outerHeight(!0)),"xaxis"==this.name?(c+=e,this._elem.css({height:c+"px",left:"0px",bottom:"0px"})):"x2axis"==this.name?(c+=e,this._elem.css({height:c+"px",left:"0px",top:"0px"})):"yaxis"==this.name?(c+=d,this._elem.css({width:c+"px",left:"0px",top:"0px"}),f&&this._label.constructor==a.jqplot.AxisLabelRenderer&&this._label._elem.css("width",d+"px")):(c+=d,this._elem.css({width:c+"px",right:"0px",top:"0px"}),f&&this._label.constructor==a.jqplot.AxisLabelRenderer&&this._label._elem.css("width",d+"px"))}},a.jqplot.LinearAxisRenderer.prototype.createTicks=function(b){var c,d,e,f,g=this._ticks,h=this.ticks,i=this.name,j=this._dataBounds,k="x"===this.name.charAt(0)?this._plotDimensions.width:this._plotDimensions.height,l=this.min,m=this.max,n=this.numberTicks,o=this.tickInterval,p=30;if(this._scalefact=(Math.max(k,p+1)-p)/300,h.length){for(f=0;f<h.length;f++){var q=h[f],r=new this.tickRenderer(this.tickOptions);a.isArray(q)?(r.value=q[0],this.breakPoints?q[0]==this.breakPoints[0]?(r.label=this.breakTickLabel,r._breakTick=!0,r.showGridline=!1,r.showMark=!1):q[0]>this.breakPoints[0]&&q[0]<=this.breakPoints[1]?(r.show=!1,r.showGridline=!1,r.label=q[1]):r.label=q[1]:r.label=q[1],r.setTick(q[0],this.name),this._ticks.push(r)):a.isPlainObject(q)?(a.extend(!0,r,q),r.axis=this.name,this._ticks.push(r)):(r.value=q,this.breakPoints&&(q==this.breakPoints[0]?(r.label=this.breakTickLabel,r._breakTick=!0,r.showGridline=!1,r.showMark=!1):q>this.breakPoints[0]&&q<=this.breakPoints[1]&&(r.show=!1,r.showGridline=!1)),r.setTick(q,this.name),this._ticks.push(r))}this.numberTicks=h.length,this.min=this._ticks[0].value,this.max=this._ticks[this.numberTicks-1].value,this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{k="xaxis"==i||"x2axis"==i?this._plotDimensions.width:this._plotDimensions.height;var s=this.numberTicks;this.alignTicks&&("x2axis"===this.name&&b.axes.xaxis.show?s=b.axes.xaxis.numberTicks:"y"===this.name.charAt(0)&&"yaxis"!==this.name&&"yMidAxis"!==this.name&&b.axes.yaxis.show&&(s=b.axes.yaxis.numberTicks)),c=null!=this.min?this.min:j.min,d=null!=this.max?this.max:j.max;var t,u,v,w=d-c;if(null!=this.tickOptions&&this.tickOptions.formatString||(this._overrideFormatString=!0),null==this.min||null==this.max&&null==this.tickInterval&&!this.autoscale){this.forceTickAt0&&(c>0&&(c=0),0>d&&(d=0)),this.forceTickAt100&&(c>100&&(c=100),100>d&&(d=100));var x=!1,y=!1;null!=this.min?x=!0:null!=this.max&&(y=!0);var z=a.jqplot.LinearTickGenerator(c,d,this._scalefact,s,x,y),A=null!=this.min?c:c+w*(this.padMin-1),B=null!=this.max?d:d-w*(this.padMax-1);(A>c||d>B)&&(A=null!=this.min?c:c-w*(this.padMin-1),B=null!=this.max?d:d+w*(this.padMax-1),z=a.jqplot.LinearTickGenerator(A,B,this._scalefact,s,x,y)),this.min=z[0],this.max=z[1],this.numberTicks=z[2],this._autoFormatString=z[3],this.tickInterval=z[4]}else{if(c==d){var C=.05;c>0&&(C=Math.max(Math.log(c)/Math.LN10,.05)),c-=C,d+=C}if(this.autoscale&&null==this.min&&null==this.max){for(var D,E,F,G=!1,H=!1,f=0;f<this._series.length;f++){var I=this._series[f],J="x"==I.fillAxis?I._xaxis.name:I._yaxis.name;if(this.name==J){for(var K=I._plotValues[I.fillAxis],L=K[0],M=K[0],N=1;N<K.length;N++)K[N]<L?L=K[N]:K[N]>M&&(M=K[N]);var O=(M-L)/M;I.renderer.constructor==a.jqplot.BarRenderer?L>=0&&(I.fillToZero||O>.1)?G=!0:(G=!1,H=I.fill&&I.fillToZero&&0>L&&M>0?!0:!1):I.fill?L>=0&&(I.fillToZero||O>.1)?G=!0:0>L&&M>0&&I.fillToZero?(G=!1,H=!0):(G=!1,H=!1):0>L&&(G=!1)}}if(G)this.numberTicks=2+Math.ceil((k-(this.tickSpacing-1))/this.tickSpacing),this.min=0,l=0,E=d/(this.numberTicks-1),v=Math.pow(10,Math.abs(Math.floor(Math.log(E)/Math.LN10))),E/v==parseInt(E/v,10)&&(E+=v),this.tickInterval=Math.ceil(E/v)*v,this.max=this.tickInterval*(this.numberTicks-1);else if(H){this.numberTicks=2+Math.ceil((k-(this.tickSpacing-1))/this.tickSpacing);var P=Math.ceil(Math.abs(c)/w*(this.numberTicks-1)),Q=this.numberTicks-1-P;E=Math.max(Math.abs(c/P),Math.abs(d/Q)),v=Math.pow(10,Math.abs(Math.floor(Math.log(E)/Math.LN10))),this.tickInterval=Math.ceil(E/v)*v,this.max=this.tickInterval*Q,this.min=-this.tickInterval*P}else null==this.numberTicks&&(this.tickInterval?this.numberTicks=3+Math.ceil(w/this.tickInterval):this.numberTicks=2+Math.ceil((k-(this.tickSpacing-1))/this.tickSpacing)),null==this.tickInterval?(E=w/(this.numberTicks-1),v=1>E?Math.pow(10,Math.abs(Math.floor(Math.log(E)/Math.LN10))):1,this.tickInterval=Math.ceil(E*v*this.pad)/v):v=1/this.tickInterval,D=this.tickInterval*(this.numberTicks-1),F=(D-w)/2,null==this.min&&(this.min=Math.floor(v*(c-F))/v),null==this.max&&(this.max=this.min+D);var R,S=a.jqplot.getSignificantFigures(this.tickInterval);if(S.digitsLeft>=S.significantDigits)R="%d";else{var v=Math.max(0,5-S.digitsLeft);v=Math.min(v,S.digitsRight),R="%."+v+"f"}this._autoFormatString=R}else{t=null!=this.min?this.min:c-w*(this.padMin-1),u=null!=this.max?this.max:d+w*(this.padMax-1),w=u-t,null==this.numberTicks&&(null!=this.tickInterval?this.numberTicks=Math.ceil((u-t)/this.tickInterval)+1:k>100?this.numberTicks=parseInt(3+(k-100)/75,10):this.numberTicks=2),null==this.tickInterval&&(this.tickInterval=w/(this.numberTicks-1)),null==this.max&&(u=t+this.tickInterval*(this.numberTicks-1)),null==this.min&&(t=u-this.tickInterval*(this.numberTicks-1));var R,S=a.jqplot.getSignificantFigures(this.tickInterval);if(S.digitsLeft>=S.significantDigits)R="%d";else{var v=Math.max(0,5-S.digitsLeft);v=Math.min(v,S.digitsRight),R="%."+v+"f"}this._autoFormatString=R,this.min=t,this.max=u}if(this.renderer.constructor==a.jqplot.LinearAxisRenderer&&""==this._autoFormatString){w=this.max-this.min;var T=new this.tickRenderer(this.tickOptions),U=T.formatString||a.jqplot.config.defaultTickFormatString,U=U.match(a.jqplot.sprintf.regex)[0],V=0;if(U){if(U.search(/[fFeEgGpP]/)>-1){var W=U.match(/\%\.(\d{0,})?[eEfFgGpP]/);V=W?parseInt(W[1],10):6}else U.search(/[di]/)>-1&&(V=0);var X=Math.pow(10,-V);if(this.tickInterval<X&&null==n&&null==o)if(this.tickInterval=X,null==m&&null==l){this.min=Math.floor(this._dataBounds.min/X)*X,this.min==this._dataBounds.min&&(this.min=this._dataBounds.min-this.tickInterval),this.max=Math.ceil(this._dataBounds.max/X)*X,this.max==this._dataBounds.max&&(this.max=this._dataBounds.max+this.tickInterval);var Y=(this.max-this.min)/this.tickInterval;Y=Y.toFixed(11),Y=Math.ceil(Y),this.numberTicks=Y+1}else if(null==m){var Y=(this._dataBounds.max-this.min)/this.tickInterval;Y=Y.toFixed(11),this.numberTicks=Math.ceil(Y)+2,this.max=this.min+this.tickInterval*(this.numberTicks-1)}else if(null==l){var Y=(this.max-this._dataBounds.min)/this.tickInterval;Y=Y.toFixed(11),this.numberTicks=Math.ceil(Y)+2,this.min=this.max-this.tickInterval*(this.numberTicks-1)}else this.numberTicks=Math.ceil((m-l)/this.tickInterval)+1,this.min=Math.floor(l*Math.pow(10,V))/Math.pow(10,V),this.max=Math.ceil(m*Math.pow(10,V))/Math.pow(10,V),this.numberTicks=Math.ceil((this.max-this.min)/this.tickInterval)+1}}}this._overrideFormatString&&""!=this._autoFormatString&&(this.tickOptions=this.tickOptions||{},this.tickOptions.formatString=this._autoFormatString);for(var r,Z,f=0;f<this.numberTicks;f++){if(e=this.min+f*this.tickInterval,r=new this.tickRenderer(this.tickOptions),r.setTick(e,this.name),this._ticks.push(r),f<this.numberTicks-1)for(var N=0;N<this.minorTicks;N++)e+=this.tickInterval/(this.minorTicks+1),Z=a.extend(!0,{},this.tickOptions,{name:this.name,value:e,label:"",isMinorTick:!0}),r=new this.tickRenderer(Z),this._ticks.push(r);r=null}}this.tickInset&&(this.min=this.min-this.tickInset*this.tickInterval,this.max=this.max+this.tickInset*this.tickInterval),g=null},a.jqplot.LinearAxisRenderer.prototype.resetTickValues=function(b){if(a.isArray(b)&&b.length==this._ticks.length){for(var c,d=0;d<b.length;d++)c=this._ticks[d],c.value=b[d],c.label=c.formatter(c.formatString,b[d]),c.label=c.prefix+c.label,c._elem.html(c.label);c=null,this.min=a.jqplot.arrayMin(b),this.max=a.jqplot.arrayMax(b),this.pack()}},a.jqplot.LinearAxisRenderer.prototype.pack=function(b,c){b=b||{},c=c||this._offsets;var d=this._ticks,e=this.max,f=this.min,g=c.max,h=c.min,i=null==this._label?!1:this._label.show;for(var j in b)this._elem.css(j,b[j]);this._offsets=c;var k=g-h,l=e-f;if(this.breakPoints?(l=l-this.breakPoints[1]+this.breakPoints[0],this.p2u=function(a){return(a-h)*l/k+f},this.u2p=function(a){return a>this.breakPoints[0]&&a<this.breakPoints[1]&&(a=this.breakPoints[0]),a<=this.breakPoints[0]?(a-f)*k/l+h:(a-this.breakPoints[1]+this.breakPoints[0]-f)*k/l+h},"x"==this.name.charAt(0)?(this.series_u2p=function(a){return a>this.breakPoints[0]&&a<this.breakPoints[1]&&(a=this.breakPoints[0]),a<=this.breakPoints[0]?(a-f)*k/l:(a-this.breakPoints[1]+this.breakPoints[0]-f)*k/l},this.series_p2u=function(a){return a*l/k+f}):(this.series_u2p=function(a){return a>this.breakPoints[0]&&a<this.breakPoints[1]&&(a=this.breakPoints[0]),a>=this.breakPoints[1]?(a-e)*k/l:(a+this.breakPoints[1]-this.breakPoints[0]-e)*k/l},this.series_p2u=function(a){return a*l/k+e})):(this.p2u=function(a){return(a-h)*l/k+f},this.u2p=function(a){return(a-f)*k/l+h},"xaxis"==this.name||"x2axis"==this.name?(this.series_u2p=function(a){return(a-f)*k/l},this.series_p2u=function(a){return a*l/k+f}):(this.series_u2p=function(a){return(a-e)*k/l},this.series_p2u=function(a){return a*l/k+e})),this.show)if("xaxis"==this.name||"x2axis"==this.name){for(var m=0;m<d.length;m++){var n=d[m];if(n.show&&n.showLabel){var o;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){var p="xaxis"==this.name?1:-1;switch(n.labelPosition){case"auto":o=p*n.angle<0?-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2:-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2;break;case"end":o=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;case"start":o=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2;break;case"middle":o=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;default:o=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2}}else o=-n.getWidth()/2;var q=this.u2p(n.value)+o+"px";n._elem.css("left",q),n.pack()}}if(i){var r=this._label._elem.outerWidth(!0);this._label._elem.css("left",h+k/2-r/2+"px"),"xaxis"==this.name?this._label._elem.css("bottom","0px"):this._label._elem.css("top","0px"),this._label.pack()}}else{for(var m=0;m<d.length;m++){var n=d[m];if(n.show&&n.showLabel){var o;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){var p="yaxis"==this.name?1:-1;switch(n.labelPosition){case"auto":case"end":o=p*n.angle<0?-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2:-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2;break;case"start":o=n.angle>0?-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2:-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2;break;case"middle":o=-n.getHeight()/2;break;default:o=-n.getHeight()/2}}else o=-n.getHeight()/2;var q=this.u2p(n.value)+o+"px";n._elem.css("top",q),n.pack()}}if(i){var s=this._label._elem.outerHeight(!0);this._label._elem.css("top",g-k/2-s/2+"px"),"yaxis"==this.name?this._label._elem.css("left","0px"):this._label._elem.css("right","0px"),this._label.pack()}}d=null};a.jqplot.LinearTickGenerator=function(b,c,d,e,f,g){if(f=null===f?!1:f,g=null===g||f?!1:g,b===c&&(c=c?0:1),d=d||1,b>c){var h=c;c=b,b=h}var i=[],j=x(c-b,d),k=a.jqplot.getSignificantFigures;if(null==e)if(f||g){if(f){i[0]=b,i[2]=Math.ceil((c-b)/j+1),i[1]=b+(i[2]-1)*j;var l=k(b).digitsRight,m=k(j).digitsRight;m>l?i[3]=u(j):i[3]="%."+l+"f",i[4]=j}else if(g){i[1]=c,i[2]=Math.ceil((c-b)/j+1),i[0]=c-(i[2]-1)*j;var n=k(c).digitsRight,m=k(j).digitsRight;m>n?i[3]=u(j):i[3]="%."+n+"f",i[4]=j}}else i[0]=Math.floor(b/j)*j,i[1]=Math.ceil(c/j)*j,i[2]=Math.round((i[1]-i[0])/j+1),i[3]=u(j),i[4]=j;else{var o=[];if(o[0]=Math.floor(b/j)*j,o[1]=Math.ceil(c/j)*j,o[2]=Math.round((o[1]-o[0])/j+1),o[3]=u(j),o[4]=j,o[2]===e)i=o;else{var p=w(o[1]-o[0],e);i[0]=o[0],i[2]=e,i[4]=p,i[3]=u(p),i[1]=i[0]+(i[2]-1)*i[4]}}return i},a.jqplot.LinearTickGenerator.bestLinearInterval=x,a.jqplot.LinearTickGenerator.bestInterval=w,a.jqplot.LinearTickGenerator.bestLinearComponents=y,a.jqplot.LinearTickGenerator.bestConstrainedInterval=v,a.jqplot.MarkerRenderer=function(b){this.show=!0,this.style="filledCircle",this.lineWidth=2,this.size=9,this.color="#666666",this.shadow=!0,this.shadowAngle=45,this.shadowOffset=1,this.shadowDepth=3,this.shadowAlpha="0.07",this.shadowRenderer=new a.jqplot.ShadowRenderer,this.shapeRenderer=new a.jqplot.ShapeRenderer,a.extend(!0,this,b)},a.jqplot.MarkerRenderer.prototype.init=function(b){a.extend(!0,this,b);var c={angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,lineWidth:this.lineWidth,depth:this.shadowDepth,closePath:!0};-1!=this.style.indexOf("filled")&&(c.fill=!0),-1!=this.style.indexOf("ircle")&&(c.isarc=!0,c.closePath=!1),this.shadowRenderer.init(c);var d={fill:!1,isarc:!1,strokeStyle:this.color,fillStyle:this.color,lineWidth:this.lineWidth,closePath:!0};-1!=this.style.indexOf("filled")&&(d.fill=!0),-1!=this.style.indexOf("ircle")&&(d.isarc=!0,d.closePath=!1),this.shapeRenderer.init(d)},a.jqplot.MarkerRenderer.prototype.drawDiamond=function(a,b,c,d,e){var f=1.2,g=this.size/2/f,h=this.size/2*f,i=[[a-g,b],[a,b+h],[a+g,b],[a,b-h]];this.shadow&&this.shadowRenderer.draw(c,i),this.shapeRenderer.draw(c,i,e)},a.jqplot.MarkerRenderer.prototype.drawPlus=function(b,c,d,e,f){var g=1,h=this.size/2*g,i=this.size/2*g,j=[[b,c-i],[b,c+i]],k=[[b+h,c],[b-h,c]],l=a.extend(!0,{},this.options,{closePath:!1});this.shadow&&(this.shadowRenderer.draw(d,j,{closePath:!1}),this.shadowRenderer.draw(d,k,{closePath:!1})),this.shapeRenderer.draw(d,j,l),this.shapeRenderer.draw(d,k,l)},a.jqplot.MarkerRenderer.prototype.drawX=function(b,c,d,e,f){var g=1,h=this.size/2*g,i=this.size/2*g,j=a.extend(!0,{},this.options,{closePath:!1}),k=[[b-h,c-i],[b+h,c+i]],l=[[b-h,c+i],[b+h,c-i]];this.shadow&&(this.shadowRenderer.draw(d,k,{closePath:!1}),this.shadowRenderer.draw(d,l,{closePath:!1})),this.shapeRenderer.draw(d,k,j),this.shapeRenderer.draw(d,l,j)},a.jqplot.MarkerRenderer.prototype.drawDash=function(a,b,c,d,e){var f=1,g=this.size/2*f,h=(this.size/2*f,[[a-g,b],[a+g,b]]);this.shadow&&this.shadowRenderer.draw(c,h),this.shapeRenderer.draw(c,h,e)},a.jqplot.MarkerRenderer.prototype.drawLine=function(a,b,c,d,e){var f=[a,b];this.shadow&&this.shadowRenderer.draw(c,f),this.shapeRenderer.draw(c,f,e)},a.jqplot.MarkerRenderer.prototype.drawSquare=function(a,b,c,d,e){var f=1,g=this.size/2/f,h=this.size/2*f,i=[[a-g,b-h],[a-g,b+h],[a+g,b+h],[a+g,b-h]];this.shadow&&this.shadowRenderer.draw(c,i),this.shapeRenderer.draw(c,i,e)},a.jqplot.MarkerRenderer.prototype.drawCircle=function(a,b,c,d,e){var f=this.size/2,g=2*Math.PI,h=[a,b,f,0,g,!0];this.shadow&&this.shadowRenderer.draw(c,h),this.shapeRenderer.draw(c,h,e)},a.jqplot.MarkerRenderer.prototype.draw=function(a,b,c,d){if(d=d||{},null==d.show||0!=d.show)switch(d.color&&!d.fillStyle&&(d.fillStyle=d.color),d.color&&!d.strokeStyle&&(d.strokeStyle=d.color),this.style){case"diamond":this.drawDiamond(a,b,c,!1,d);break;case"filledDiamond":this.drawDiamond(a,b,c,!0,d);break;case"circle":this.drawCircle(a,b,c,!1,d);break;case"filledCircle":this.drawCircle(a,b,c,!0,d);break;case"square":this.drawSquare(a,b,c,!1,d);break;case"filledSquare":this.drawSquare(a,b,c,!0,d);break;case"x":this.drawX(a,b,c,!0,d);break;case"plus":this.drawPlus(a,b,c,!0,d);break;case"dash":this.drawDash(a,b,c,!0,d);break;case"line":this.drawLine(a,b,c,!1,d);break;default:this.drawDiamond(a,b,c,!1,d)}},a.jqplot.ShadowRenderer=function(b){this.angle=45,this.offset=1,this.alpha=.07,this.lineWidth=1.5,this.lineJoin="miter",this.lineCap="round",this.closePath=!1,this.fill=!1,this.depth=3,this.strokeStyle="rgba(0,0,0,0.1)",this.isarc=!1,a.extend(!0,this,b)},a.jqplot.ShadowRenderer.prototype.init=function(b){a.extend(!0,this,b)},a.jqplot.ShadowRenderer.prototype.draw=function(b,c,d){b.save();var e=null!=d?d:{},f=null!=e.fill?e.fill:this.fill,g=null!=e.fillRect?e.fillRect:this.fillRect,h=null!=e.closePath?e.closePath:this.closePath,i=null!=e.offset?e.offset:this.offset,j=null!=e.alpha?e.alpha:this.alpha,k=null!=e.depth?e.depth:this.depth,l=null!=e.isarc?e.isarc:this.isarc,m=null!=e.linePattern?e.linePattern:this.linePattern;b.lineWidth=null!=e.lineWidth?e.lineWidth:this.lineWidth,b.lineJoin=null!=e.lineJoin?e.lineJoin:this.lineJoin,b.lineCap=null!=e.lineCap?e.lineCap:this.lineCap,b.strokeStyle=e.strokeStyle||this.strokeStyle||"rgba(0,0,0,"+j+")",b.fillStyle=e.fillStyle||this.fillStyle||"rgba(0,0,0,"+j+")";for(var n=0;k>n;n++){var o=a.jqplot.LinePattern(b,m);if(b.translate(Math.cos(this.angle*Math.PI/180)*i,Math.sin(this.angle*Math.PI/180)*i),o.beginPath(),l)b.arc(c[0],c[1],c[2],c[3],c[4],!0);else if(g)g&&b.fillRect(c[0],c[1],c[2],c[3]);else if(c&&c.length)for(var p=!0,q=0;q<c.length;q++)null!=c[q][0]&&null!=c[q][1]?p?(o.moveTo(c[q][0],c[q][1]),p=!1):o.lineTo(c[q][0],c[q][1]):p=!0;h&&o.closePath(),f?b.fill():b.stroke()}b.restore()},a.jqplot.ShapeRenderer=function(b){this.lineWidth=1.5,this.linePattern="solid",this.lineJoin="miter",this.lineCap="round",this.closePath=!1,this.fill=!1,this.isarc=!1,this.fillRect=!1,this.strokeRect=!1,this.clearRect=!1,this.strokeStyle="#999999",this.fillStyle="#999999",a.extend(!0,this,b)},a.jqplot.ShapeRenderer.prototype.init=function(b){a.extend(!0,this,b)},a.jqplot.ShapeRenderer.prototype.draw=function(b,c,d){b.save();var e=null!=d?d:{},f=null!=e.fill?e.fill:this.fill,g=null!=e.closePath?e.closePath:this.closePath,h=null!=e.fillRect?e.fillRect:this.fillRect,i=null!=e.strokeRect?e.strokeRect:this.strokeRect,j=null!=e.clearRect?e.clearRect:this.clearRect,k=null!=e.isarc?e.isarc:this.isarc,l=null!=e.linePattern?e.linePattern:this.linePattern,m=a.jqplot.LinePattern(b,l);if(b.lineWidth=e.lineWidth||this.lineWidth,b.lineJoin=e.lineJoin||this.lineJoin,b.lineCap=e.lineCap||this.lineCap,b.strokeStyle=e.strokeStyle||e.color||this.strokeStyle,b.fillStyle=e.fillStyle||this.fillStyle,b.beginPath(),k)return b.arc(c[0],c[1],c[2],c[3],c[4],!0),g&&b.closePath(),f?b.fill():b.stroke(),void b.restore();if(j)return b.clearRect(c[0],c[1],c[2],c[3]),void b.restore();if(h||i){if(h&&b.fillRect(c[0],c[1],c[2],c[3]),i)return b.strokeRect(c[0],c[1],c[2],c[3]),void b.restore()}else if(c&&c.length){for(var n=!0,o=0;o<c.length;o++)null!=c[o][0]&&null!=c[o][1]?n?(m.moveTo(c[o][0],c[o][1]),n=!1):m.lineTo(c[o][0],c[o][1]):n=!0;g&&m.closePath(),f?b.fill():b.stroke()}b.restore()},a.jqplot.TableLegendRenderer=function(){},a.jqplot.TableLegendRenderer.prototype.init=function(b){a.extend(!0,this,b)},a.jqplot.TableLegendRenderer.prototype.addrow=function(b,c,d,e){var f,g,h,i,j,k=d?this.rowSpacing+"px":"0px";h=document.createElement("tr"),f=a(h),f.addClass("jqplot-table-legend"),h=null,e?f.prependTo(this._elem):f.appendTo(this._elem),this.showSwatches&&(g=a(document.createElement("td")),g.addClass("jqplot-table-legend jqplot-table-legend-swatch"),g.css({textAlign:"center",paddingTop:k}),i=a(document.createElement("div")),i.addClass("jqplot-table-legend-swatch-outline"),j=a(document.createElement("div")),j.addClass("jqplot-table-legend-swatch"),j.css({backgroundColor:c,borderColor:c}),f.append(g.append(i.append(j)))),this.showLabels&&(g=a(document.createElement("td")),g.addClass("jqplot-table-legend jqplot-table-legend-label"),g.css("paddingTop",k),f.append(g),this.escapeHtml?g.text(b):g.html(b)),g=null,i=null,j=null,f=null,h=null},a.jqplot.TableLegendRenderer.prototype.draw=function(){if(this._elem&&(this._elem.emptyForce(),this._elem=null),this.show){var b=this._series,c=document.createElement("table");this._elem=a(c),this._elem.addClass("jqplot-table-legend");var d={position:"absolute"};this.background&&(d.background=this.background),this.border&&(d.border=this.border),this.fontSize&&(d.fontSize=this.fontSize),this.fontFamily&&(d.fontFamily=this.fontFamily),this.textColor&&(d.textColor=this.textColor),null!=this.marginTop&&(d.marginTop=this.marginTop),null!=this.marginBottom&&(d.marginBottom=this.marginBottom),null!=this.marginLeft&&(d.marginLeft=this.marginLeft),null!=this.marginRight&&(d.marginRight=this.marginRight);for(var e,f=!1,g=!1,h=0;h<b.length;h++)if(e=b[h],(e._stack||e.renderer.constructor==a.jqplot.BezierCurveRenderer)&&(g=!0),e.show&&e.showLabel){var i=this.labels[h]||e.label.toString();if(i){var j=e.color;g&&h<b.length-1?f=!0:g&&h==b.length-1&&(f=!1),this.renderer.addrow.call(this,i,j,f,g),f=!0}for(var k=0;k<a.jqplot.addLegendRowHooks.length;k++){var l=a.jqplot.addLegendRowHooks[k].call(this,e);l&&(this.renderer.addrow.call(this,l.label,l.color,f),f=!0)}i=null}}return this._elem},a.jqplot.TableLegendRenderer.prototype.pack=function(a){if(this.show)if("insideGrid"==this.placement)switch(this.location){case"nw":var b=a.left,c=a.top;this._elem.css("left",b),this._elem.css("top",c);break;case"n":var b=(a.left+(this._plotDimensions.width-a.right))/2-this.getWidth()/2,c=a.top;this._elem.css("left",b),this._elem.css("top",c);break;case"ne":var b=a.right,c=a.top;this._elem.css({right:b,top:c});break;case"e":var b=a.right,c=(a.top+(this._plotDimensions.height-a.bottom))/2-this.getHeight()/2;this._elem.css({right:b,top:c});break;case"se":var b=a.right,c=a.bottom;this._elem.css({right:b,bottom:c});break;case"s":var b=(a.left+(this._plotDimensions.width-a.right))/2-this.getWidth()/2,c=a.bottom;this._elem.css({left:b,bottom:c});break;case"sw":var b=a.left,c=a.bottom;this._elem.css({left:b,bottom:c});break;case"w":var b=a.left,c=(a.top+(this._plotDimensions.height-a.bottom))/2-this.getHeight()/2;this._elem.css({left:b,top:c});break;default:var b=a.right,c=a.bottom;this._elem.css({right:b,bottom:c})}else if("outside"==this.placement)switch(this.location){case"nw":var b=this._plotDimensions.width-a.left,c=a.top;this._elem.css("right",b),this._elem.css("top",c);break;case"n":var b=(a.left+(this._plotDimensions.width-a.right))/2-this.getWidth()/2,c=this._plotDimensions.height-a.top;this._elem.css("left",b),this._elem.css("bottom",c);break;case"ne":var b=this._plotDimensions.width-a.right,c=a.top;this._elem.css({left:b,top:c});break;case"e":var b=this._plotDimensions.width-a.right,c=(a.top+(this._plotDimensions.height-a.bottom))/2-this.getHeight()/2;this._elem.css({left:b,top:c});break;case"se":var b=this._plotDimensions.width-a.right,c=a.bottom;this._elem.css({left:b,bottom:c});break;case"s":var b=(a.left+(this._plotDimensions.width-a.right))/2-this.getWidth()/2,c=this._plotDimensions.height-a.bottom;this._elem.css({left:b,top:c});break;case"sw":var b=this._plotDimensions.width-a.left,c=a.bottom;this._elem.css({right:b,bottom:c});break;case"w":var b=this._plotDimensions.width-a.left,c=(a.top+(this._plotDimensions.height-a.bottom))/2-this.getHeight()/2;this._elem.css({right:b,top:c});break;default:var b=a.right,c=a.bottom;this._elem.css({right:b,bottom:c})}else switch(this.location){case"nw":this._elem.css({left:0,top:a.top});break;case"n":var b=(a.left+(this._plotDimensions.width-a.right))/2-this.getWidth()/2;this._elem.css({left:b,top:a.top});break;case"ne":this._elem.css({right:0,top:a.top});break;case"e":var c=(a.top+(this._plotDimensions.height-a.bottom))/2-this.getHeight()/2;this._elem.css({right:a.right,top:c});break;case"se":this._elem.css({right:a.right,bottom:a.bottom});break;case"s":var b=(a.left+(this._plotDimensions.width-a.right))/2-this.getWidth()/2;this._elem.css({left:b,bottom:a.bottom});break;case"sw":this._elem.css({left:a.left,bottom:a.bottom});break;case"w":var c=(a.top+(this._plotDimensions.height-a.bottom))/2-this.getHeight()/2;this._elem.css({left:a.left,top:c});break;default:this._elem.css({right:a.right,bottom:a.bottom})}},a.jqplot.ThemeEngine=function(){this.themes={},this.activeTheme=null},a.jqplot.ThemeEngine.prototype.init=function(){var b,c,d,e=new a.jqplot.Theme({_name:"Default"});for(b in e.target)"textColor"==b?e.target[b]=this.target.css("color"):e.target[b]=this.target.css(b);if(this.title.show&&this.title._elem)for(b in e.title)"textColor"==b?e.title[b]=this.title._elem.css("color"):e.title[b]=this.title._elem.css(b);for(b in e.grid)e.grid[b]=this.grid[b];if(null==e.grid.backgroundColor&&null!=this.grid.background&&(e.grid.backgroundColor=this.grid.background),this.legend.show&&this.legend._elem)for(b in e.legend)"textColor"==b?e.legend[b]=this.legend._elem.css("color"):e.legend[b]=this.legend._elem.css(b);var f;for(c=0;c<this.series.length;c++){f=this.series[c],f.renderer.constructor==a.jqplot.LineRenderer?e.series.push(new L):f.renderer.constructor==a.jqplot.BarRenderer?e.series.push(new N):f.renderer.constructor==a.jqplot.PieRenderer?e.series.push(new O):f.renderer.constructor==a.jqplot.DonutRenderer?e.series.push(new P):f.renderer.constructor==a.jqplot.FunnelRenderer?e.series.push(new Q):f.renderer.constructor==a.jqplot.MeterGaugeRenderer?e.series.push(new R):e.series.push({});for(b in e.series[c])e.series[c][b]=f[b]}var g,h;for(b in this.axes){if(h=this.axes[b],g=e.axes[b]=new I,g.borderColor=h.borderColor,g.borderWidth=h.borderWidth,h._ticks&&h._ticks[0])for(d in g.ticks)h._ticks[0].hasOwnProperty(d)?g.ticks[d]=h._ticks[0][d]:h._ticks[0]._elem&&(g.ticks[d]=h._ticks[0]._elem.css(d));if(h._label&&h._label.show)for(d in g.label)h._label[d]?g.label[d]=h._label[d]:h._label._elem&&("textColor"==d?g.label[d]=h._label._elem.css("color"):g.label[d]=h._label._elem.css(d))}this.themeEngine._add(e),this.themeEngine.activeTheme=this.themeEngine.themes[e._name]},a.jqplot.ThemeEngine.prototype.get=function(a){return a?this.themes[a]:this.activeTheme},a.jqplot.ThemeEngine.prototype.getThemeNames=function(){var a=[];for(var b in this.themes)a.push(b);return a.sort(z)},a.jqplot.ThemeEngine.prototype.getThemes=function(){var a=[],b=[];for(var c in this.themes)a.push(c);a.sort(z);for(var d=0;d<a.length;d++)b.push(this.themes[a[d]]);return b},a.jqplot.ThemeEngine.prototype.activate=function(b,c){var d=!1;if(!c&&this.activeTheme&&this.activeTheme._name&&(c=this.activeTheme._name),!this.themes.hasOwnProperty(c))throw new Error("No theme of that name");var e=this.themes[c];this.activeTheme=e;var f,g=["xaxis","x2axis","yaxis","y2axis"];for(p=0;p<g.length;p++){var h=g[p];null!=e.axesStyles.borderColor&&(b.axes[h].borderColor=e.axesStyles.borderColor),null!=e.axesStyles.borderWidth&&(b.axes[h].borderWidth=e.axesStyles.borderWidth)}for(var i in b.axes){var j=b.axes[i];if(j.show){var k=e.axes[i]||{},l=e.axesStyles,m=a.jqplot.extend(!0,{},k,l);if(f=null!=e.axesStyles.borderColor?e.axesStyles.borderColor:m.borderColor,null!=m.borderColor&&(j.borderColor=m.borderColor,d=!0),f=null!=e.axesStyles.borderWidth?e.axesStyles.borderWidth:m.borderWidth,null!=m.borderWidth&&(j.borderWidth=m.borderWidth,d=!0),j._ticks&&j._ticks[0])for(var n in m.ticks)f=m.ticks[n],null!=f&&(j.tickOptions[n]=f,j._ticks=[],d=!0);if(j._label&&j._label.show)for(var n in m.label)f=m.label[n],null!=f&&(j.labelOptions[n]=f,d=!0)}}for(var o in e.grid)null!=e.grid[o]&&(b.grid[o]=e.grid[o]);if(d||b.grid.draw(),b.legend.show)for(o in e.legend)null!=e.legend[o]&&(b.legend[o]=e.legend[o]);if(b.title.show)for(o in e.title)null!=e.title[o]&&(b.title[o]=e.title[o]);var p;for(p=0;p<e.series.length;p++){var q={};for(o in e.series[p])f=null!=e.seriesStyles[o]?e.seriesStyles[o]:e.series[p][o],null!=f&&(q[o]=f,"color"==o?(b.series[p].renderer.shapeRenderer.fillStyle=f,b.series[p].renderer.shapeRenderer.strokeStyle=f,b.series[p][o]=f):"lineWidth"==o||"linePattern"==o?(b.series[p].renderer.shapeRenderer[o]=f,b.series[p][o]=f):"markerOptions"==o?(B(b.series[p].markerOptions,f),B(b.series[p].markerRenderer,f)):b.series[p][o]=f,d=!0)}d&&(b.target.empty(),b.draw());for(o in e.target)null!=e.target[o]&&b.target.css(o,e.target[o])},a.jqplot.ThemeEngine.prototype._add=function(a,b){if(b&&(a._name=b),a._name||(a._name=Date.parse(new Date)),this.themes.hasOwnProperty(a._name))throw new Error("jqplot.ThemeEngine Error: Theme already in use");this.themes[a._name]=a},a.jqplot.ThemeEngine.prototype.remove=function(a){return"Default"==a?!1:delete this.themes[a]},a.jqplot.ThemeEngine.prototype.newTheme=function(b,c){"object"==typeof b&&(c=c||b,b=null),b=c&&c._name?c._name:b||Date.parse(new Date);var d=this.copy(this.themes.Default._name,b);return a.jqplot.extend(d,c),d},a.jqplot.clone=A,a.jqplot.merge=B,a.jqplot.extend=function(){var b,c=arguments[0]||{},d=1,e=arguments.length,f=!1;for("boolean"==typeof c&&(f=c,c=arguments[1]||{},d=2),"object"!=typeof c&&"[object Function]"===!toString.call(c)&&(c={});e>d;d++)if(null!=(b=arguments[d]))for(var g in b){var h=c[g],i=b[g];c!==i&&(f&&i&&"object"==typeof i&&!i.nodeType?c[g]=a.jqplot.extend(f,h||(null!=i.length?[]:{}),i):i!==F&&(c[g]=i))}return c},a.jqplot.ThemeEngine.prototype.rename=function(a,b){if("Default"==a||"Default"==b)throw new Error("jqplot.ThemeEngine Error: Cannot rename from/to Default");if(this.themes.hasOwnProperty(b))throw new Error("jqplot.ThemeEngine Error: New name already in use.");if(this.themes.hasOwnProperty(a)){var c=this.copy(a,b);return this.remove(a),c}throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid")},a.jqplot.ThemeEngine.prototype.copy=function(b,c,d){if("Default"==c)throw new Error("jqplot.ThemeEngine Error: Cannot copy over Default theme");if(!this.themes.hasOwnProperty(b)){var e="jqplot.ThemeEngine Error: Source name invalid";throw new Error(e)}if(this.themes.hasOwnProperty(c)){var e="jqplot.ThemeEngine Error: Target name invalid";throw new Error(e)}var f=A(this.themes[b]);return f._name=c,a.jqplot.extend(!0,f,d),this._add(f),f},a.jqplot.Theme=function(b,c){"object"==typeof b&&(c=c||b,b=null),b=b||Date.parse(new Date),this._name=b,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={},"string"==typeof c?this._name=c:"object"==typeof c&&a.jqplot.extend(!0,this,c)};var I=function(){this.borderColor=null,this.borderWidth=null,this.ticks=new J,this.label=new K},J=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},K=function(){this.textColor=null,this.whiteSpace=null,this.fontSize=null,
|
8 |
+
this.fontFamily=null,this.fontWeight=null},L=function(){this.color=null,this.lineWidth=null,this.linePattern=null,this.shadow=null,this.fillColor=null,this.showMarker=null,this.markerOptions=new M},M=function(){this.show=null,this.style=null,this.lineWidth=null,this.size=null,this.color=null,this.shadow=null},N=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},O=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},P=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},Q=function(){this.color=null,this.lineWidth=null,this.shadow=null,this.padding=null,this.sectionMargin=null,this.seriesColors=null,this.highlightColors=null},R=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};a.fn.jqplotChildText=function(){return a(this).contents().filter(function(){return 3==this.nodeType}).text()},a.fn.jqplotGetComputedFontStyle=function(){for(var a=window.getComputedStyle?window.getComputedStyle(this[0],""):this[0].currentStyle,b=a["font-style"]?["font-style","font-weight","font-size","font-family"]:["fontStyle","fontWeight","fontSize","fontFamily"],c=[],d=0;d<b.length;++d){var e=String(a[b[d]]);e&&"normal"!=e&&c.push(e)}return c.join(" ")},a.fn.jqplotToImageCanvas=function(b){function c(b){var c=parseInt(a(b).css("line-height"),10);return isNaN(c)&&(c=1.2*parseInt(a(b).css("font-size"),10)),c}function d(b,d,e,f,g,h){for(var i=c(b),j=a(b).innerWidth(),k=(a(b).innerHeight(),e.split(/\s+/)),l=k.length,m="",n=[],o=g,p=f,q=0;l>q;q++)m+=k[q],d.measureText(m).width>j&&m.length>k[q].length&&(n.push(q),m="",q--);if(0===n.length)"center"===a(b).css("textAlign")&&(p=f+(h-d.measureText(m).width)/2-s),d.fillText(e,p,g);else{m=k.slice(0,n[0]).join(" "),"center"===a(b).css("textAlign")&&(p=f+(h-d.measureText(m).width)/2-s),d.fillText(m,p,o),o+=i;for(var q=1,r=n.length;r>q;q++)m=k.slice(n[q-1],n[q]).join(" "),"center"===a(b).css("textAlign")&&(p=f+(h-d.measureText(m).width)/2-s),d.fillText(m,p,o),o+=i;m=k.slice(n[q-1],k.length).join(" "),"center"===a(b).css("textAlign")&&(p=f+(h-d.measureText(m).width)/2-s),d.fillText(m,p,o)}}function e(b,c,f){var g=b.tagName.toLowerCase(),h=a(b).position(),i=window.getComputedStyle?window.getComputedStyle(b,""):b.currentStyle,j=c+h.left+parseInt(i.marginLeft,10)+parseInt(i.borderLeftWidth,10)+parseInt(i.paddingLeft,10),k=f+h.top+parseInt(i.marginTop,10)+parseInt(i.borderTopWidth,10)+parseInt(i.paddingTop,10),l=m.width;if("div"!=g&&"span"!=g||a(b).hasClass("jqplot-highlighter-tooltip"))if("table"===g&&a(b).hasClass("jqplot-table-legend")){w.strokeStyle=a(b).css("border-top-color"),w.fillStyle=a(b).css("background-color"),w.fillRect(j,k,a(b).innerWidth(),a(b).innerHeight()),parseInt(a(b).css("border-top-width"),10)>0&&w.strokeRect(j,k,a(b).innerWidth(),a(b).innerHeight()),a(b).find("div.jqplot-table-legend-swatch-outline").each(function(){var b=a(this);w.strokeStyle=b.css("border-top-color");var c=j+b.position().left,d=k+b.position().top;w.strokeRect(c,d,b.innerWidth(),b.innerHeight()),c+=parseInt(b.css("padding-left"),10),d+=parseInt(b.css("padding-top"),10);var e=b.innerHeight()-2*parseInt(b.css("padding-top"),10),f=b.innerWidth()-2*parseInt(b.css("padding-left"),10),g=b.children("div.jqplot-table-legend-swatch");w.fillStyle=g.css("background-color"),w.fillRect(c,d,f,e)}),a(b).find("td.jqplot-table-legend-label").each(function(){var b=a(this),c=j+b.position().left,e=k+b.position().top+parseInt(b.css("padding-top"),10);w.font=b.jqplotGetComputedFontStyle(),w.fillStyle=b.css("color"),d(b,w,b.text(),c,e,l)})}else"canvas"==g&&w.drawImage(b,j,k);else{a(b).children().each(function(){e(this,j,k)});var n=a(b).jqplotChildText();n&&(w.font=a(b).jqplotGetComputedFontStyle(),w.fillStyle=a(b).css("color"),d(b,w,n,j,k,l))}}b=b||{};var f=null==b.x_offset?0:b.x_offset,g=null==b.y_offset?0:b.y_offset,h=null==b.backgroundColor?"rgb(255,255,255)":b.backgroundColor;if(0==a(this).width()||0==a(this).height())return null;if(a.jqplot.use_excanvas)return null;for(var i,j,k,l,m=document.createElement("canvas"),n=a(this).outerHeight(!0),o=a(this).outerWidth(!0),p=a(this).offset(),q=p.left,r=p.top,s=0,t=0,u=["jqplot-table-legend","jqplot-xaxis-tick","jqplot-x2axis-tick","jqplot-yaxis-tick","jqplot-y2axis-tick","jqplot-y3axis-tick","jqplot-y4axis-tick","jqplot-y5axis-tick","jqplot-y6axis-tick","jqplot-y7axis-tick","jqplot-y8axis-tick","jqplot-y9axis-tick","jqplot-xaxis-label","jqplot-x2axis-label","jqplot-yaxis-label","jqplot-y2axis-label","jqplot-y3axis-label","jqplot-y4axis-label","jqplot-y5axis-label","jqplot-y6axis-label","jqplot-y7axis-label","jqplot-y8axis-label","jqplot-y9axis-label"],v=0;v<u.length;v++)a(this).find("."+u[v]).each(function(){i=a(this).offset().top-r,j=a(this).offset().left-q,l=j+a(this).outerWidth(!0)+s,k=i+a(this).outerHeight(!0)+t,-s>j&&(o=o-s-j,s=-j),-t>i&&(n=n-t-i,t=-i),l>o&&(o=l),k>n&&(n=k)});m.width=o+Number(f),m.height=n+Number(g);var w=m.getContext("2d");return w.save(),w.fillStyle=h,w.fillRect(0,0,m.width,m.height),w.restore(),w.translate(s,t),w.textAlign="left",w.textBaseline="top",a(this).children().each(function(){e(this,f,g)}),m},a.fn.jqplotToImageStr=function(b){var c=a(this).jqplotToImageCanvas(b);return c?c.toDataURL("image/png"):null},a.fn.jqplotToImageElem=function(b){var c=document.createElement("img"),d=a(this).jqplotToImageStr(b);return c.src=d,c},a.fn.jqplotToImageElemStr=function(b){var c="<img src="+a(this).jqplotToImageStr(b)+" />";return c},a.fn.jqplotSaveImage=function(){var b=a(this).jqplotToImageStr({});b&&(window.location.href=b.replace("image/png","image/octet-stream"))},a.fn.jqplotViewImage=function(){var b=a(this).jqplotToImageElemStr({});a(this).jqplotToImageStr({});if(b){var c=window.open("");c.document.open("image/png"),c.document.write(b),c.document.close(),c=null}};var S=function(){switch(this.syntax=S.config.syntax,this._type="jsDate",this.proxy=new Date,this.options={},this.locale=S.regional.getLocale(),this.formatString="",this.defaultCentury=S.config.defaultCentury,arguments.length){case 0:break;case 1:if("[object Object]"==D(arguments[0])&&"jsDate"!=arguments[0]._type){var a=this.options=arguments[0];this.syntax=a.syntax||this.syntax,this.defaultCentury=a.defaultCentury||this.defaultCentury,this.proxy=S.createDate(a.date)}else this.proxy=S.createDate(arguments[0]);break;default:for(var b=[],c=0;c<arguments.length;c++)b.push(arguments[c]);this.proxy=new Date,this.proxy.setFullYear.apply(this.proxy,b.slice(0,3)),b.slice(3).length&&this.proxy.setHours.apply(this.proxy,b.slice(3))}};S.config={defaultLocale:"en",syntax:"perl",defaultCentury:1900},S.prototype.add=function(a,b){var c=V[b]||V.day;return"number"==typeof c?this.proxy.setTime(this.proxy.getTime()+c*a):c.add(this,a),this},S.prototype.clone=function(){return new S(this.proxy.getTime())},S.prototype.getUtcOffset=function(){return 6e4*this.proxy.getTimezoneOffset()},S.prototype.diff=function(a,b,c){if(a=new S(a),null===a)return null;var d=V[b]||V.day;if("number"==typeof d)var e=(this.proxy.getTime()-a.proxy.getTime())/d;else var e=d.diff(this.proxy,a.proxy);return c?e:Math[e>0?"floor":"ceil"](e)},S.prototype.getAbbrDayName=function(){return S.regional[this.locale].dayNamesShort[this.proxy.getDay()]},S.prototype.getAbbrMonthName=function(){return S.regional[this.locale].monthNamesShort[this.proxy.getMonth()]},S.prototype.getAMPM=function(){return this.proxy.getHours()>=12?"PM":"AM"},S.prototype.getAmPm=function(){return this.proxy.getHours()>=12?"pm":"am"},S.prototype.getCentury=function(){return parseInt(this.proxy.getFullYear()/100,10)},S.prototype.getDate=function(){return this.proxy.getDate()},S.prototype.getDay=function(){return this.proxy.getDay()},S.prototype.getDayOfWeek=function(){var a=this.proxy.getDay();return 0===a?7:a},S.prototype.getDayOfYear=function(){var a=this.proxy,b=a-new Date(""+a.getFullYear()+"/1/1 GMT");return b+=6e4*a.getTimezoneOffset(),a=null,parseInt(b/6e4/60/24,10)+1},S.prototype.getDayName=function(){return S.regional[this.locale].dayNames[this.proxy.getDay()]},S.prototype.getFullWeekOfYear=function(){var a=this.proxy,b=this.getDayOfYear(),c=6-a.getDay(),d=parseInt((b+c)/7,10);return d},S.prototype.getFullYear=function(){return this.proxy.getFullYear()},S.prototype.getGmtOffset=function(){var a=this.proxy.getTimezoneOffset()/60,b=0>a?"+":"-";return a=Math.abs(a),b+U(Math.floor(a),2)+":"+U(a%1*60,2)},S.prototype.getHours=function(){return this.proxy.getHours()},S.prototype.getHours12=function(){var a=this.proxy.getHours();return a>12?a-12:0==a?12:a},S.prototype.getIsoWeek=function(){var a=this.proxy,b=this.getWeekOfYear(),c=new Date(""+a.getFullYear()+"/1/1").getDay(),d=b+(c>4||1>=c?0:1);return 53==d&&new Date(""+a.getFullYear()+"/12/31").getDay()<4?d=1:0===d&&(a=new S(new Date(""+(a.getFullYear()-1)+"/12/31")),d=a.getIsoWeek()),a=null,d},S.prototype.getMilliseconds=function(){return this.proxy.getMilliseconds()},S.prototype.getMinutes=function(){return this.proxy.getMinutes()},S.prototype.getMonth=function(){return this.proxy.getMonth()},S.prototype.getMonthName=function(){return S.regional[this.locale].monthNames[this.proxy.getMonth()]},S.prototype.getMonthNumber=function(){return this.proxy.getMonth()+1},S.prototype.getSeconds=function(){return this.proxy.getSeconds()},S.prototype.getShortYear=function(){return this.proxy.getYear()%100},S.prototype.getTime=function(){return this.proxy.getTime()},S.prototype.getTimezoneAbbr=function(){return this.proxy.toString().replace(/^.*\(([^)]+)\)$/,"$1")},S.prototype.getTimezoneName=function(){var a=/(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());return a[1]||a[2]||"GMT"+this.getGmtOffset()},S.prototype.getTimezoneOffset=function(){return this.proxy.getTimezoneOffset()},S.prototype.getWeekOfYear=function(){var a=this.getDayOfYear(),b=7-this.getDayOfWeek(),c=parseInt((a+b)/7,10);return c},S.prototype.getUnix=function(){return Math.round(this.proxy.getTime()/1e3,0)},S.prototype.getYear=function(){return this.proxy.getYear()},S.prototype.next=function(a){return a=a||"day",this.clone().add(1,a)},S.prototype.set=function(){switch(arguments.length){case 0:this.proxy=new Date;break;case 1:if("[object Object]"==D(arguments[0])&&"jsDate"!=arguments[0]._type){var a=this.options=arguments[0];this.syntax=a.syntax||this.syntax,this.defaultCentury=a.defaultCentury||this.defaultCentury,this.proxy=S.createDate(a.date)}else this.proxy=S.createDate(arguments[0]);break;default:for(var b=[],c=0;c<arguments.length;c++)b.push(arguments[c]);this.proxy=new Date,this.proxy.setFullYear.apply(this.proxy,b.slice(0,3)),b.slice(3).length&&this.proxy.setHours.apply(this.proxy,b.slice(3))}return this},S.prototype.setDate=function(a){return this.proxy.setDate(a),this},S.prototype.setFullYear=function(){return this.proxy.setFullYear.apply(this.proxy,arguments),this},S.prototype.setHours=function(){return this.proxy.setHours.apply(this.proxy,arguments),this},S.prototype.setMilliseconds=function(a){return this.proxy.setMilliseconds(a),this},S.prototype.setMinutes=function(){return this.proxy.setMinutes.apply(this.proxy,arguments),this},S.prototype.setMonth=function(){return this.proxy.setMonth.apply(this.proxy,arguments),this},S.prototype.setSeconds=function(){return this.proxy.setSeconds.apply(this.proxy,arguments),this},S.prototype.setTime=function(a){return this.proxy.setTime(a),this},S.prototype.setYear=function(){return this.proxy.setYear.apply(this.proxy,arguments),this},S.prototype.strftime=function(a){return a=a||this.formatString||S.regional[this.locale].formatString,S.strftime(this,a,this.syntax)},S.prototype.toString=function(){return this.proxy.toString()},S.prototype.toYmdInt=function(){return 1e4*this.proxy.getFullYear()+100*this.getMonthNumber()+this.proxy.getDate()},S.regional={en:{monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],formatString:"%Y-%m-%d %H:%M:%S"},fr:{monthNames:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],monthNamesShort:["Jan","Fév","Mar","Avr","Mai","Jun","Jul","Aoû","Sep","Oct","Nov","Déc"],dayNames:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],dayNamesShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],formatString:"%Y-%m-%d %H:%M:%S"},de:{monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],formatString:"%Y-%m-%d %H:%M:%S"},es:{monthNames:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],monthNamesShort:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],dayNames:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"],dayNamesShort:["Dom","Lun","Mar","Mié","Juv","Vie","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},ru:{monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],dayNamesShort:["вск","пнд","втр","срд","чтв","птн","сбт"],formatString:"%Y-%m-%d %H:%M:%S"},ar:{monthNames:["كانون الثاني","شباط","آذار","نيسان","آذار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["السبت","الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة"],dayNamesShort:["سبت","أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة"],formatString:"%Y-%m-%d %H:%M:%S"},pt:{monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},"pt-BR":{monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},pl:{monthNames:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthNamesShort:["Sty","Lut","Mar","Kwi","Maj","Cze","Lip","Sie","Wrz","Paź","Lis","Gru"],dayNames:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],dayNamesShort:["Ni","Pn","Wt","Śr","Cz","Pt","Sb"],formatString:"%Y-%m-%d %H:%M:%S"},nl:{monthNames:["Januari","Februari","Maart","April","Mei","Juni","July","Augustus","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNames:",".Zaterdag,dayNamesShort:["Zo","Ma","Di","Wo","Do","Vr","Za"],formatString:"%Y-%m-%d %H:%M:%S"},sv:{monthNames:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthNamesShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],dayNames:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],dayNamesShort:["sön","mån","tis","ons","tor","fre","lör"],formatString:"%Y-%m-%d %H:%M:%S"},it:{monthNames:["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],monthNamesShort:["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],dayNames:["Domenica","Lunedi","Martedi","Mercoledi","Giovedi","Venerdi","Sabato"],dayNamesShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],formatString:"%d-%m-%Y %H:%M:%S"}},S.regional["en-US"]=S.regional["en-GB"]=S.regional.en,S.regional.getLocale=function(){var a=S.config.defaultLocale;return document&&document.getElementsByTagName("html")&&document.getElementsByTagName("html")[0].lang&&(a=document.getElementsByTagName("html")[0].lang,S.regional.hasOwnProperty(a)||(a=S.config.defaultLocale)),a};var T=864e5,U=function(a,b){a=String(a);var c=b-a.length,d=String(Math.pow(10,c)).slice(1);return d.concat(a)},V={millisecond:1,second:1e3,minute:6e4,hour:36e5,day:T,week:7*T,month:{add:function(a,b){V.year.add(a,Math[b>0?"floor":"ceil"](b/12));var c=a.getMonth()+b%12;12==c?(c=0,a.setYear(a.getFullYear()+1)):-1==c&&(c=11,a.setYear(a.getFullYear()-1)),a.setMonth(c)},diff:function(a,b){var c=a.getFullYear()-b.getFullYear(),d=a.getMonth()-b.getMonth()+12*c,e=a.getDate()-b.getDate();return d+e/30}},year:{add:function(a,b){a.setYear(a.getFullYear()+Math[b>0?"floor":"ceil"](b))},diff:function(a,b){return V.month.diff(a,b)/12}}};for(var W in V)"s"!=W.substring(W.length-1)&&(V[W+"s"]=V[W]);var X=function(a,b,c){if(S.formats[c].shortcuts[b])return S.strftime(a,S.formats[c].shortcuts[b],c);var d=(S.formats[c].codes[b]||"").split("."),e=a["get"+d[0]]?a["get"+d[0]]():"";return d[1]&&(e=U(e,d[1])),e};S.strftime=function(a,b,c,d){var e="perl",f=S.regional.getLocale();c&&S.formats.hasOwnProperty(c)?e=c:c&&S.regional.hasOwnProperty(c)&&(f=c),d&&S.formats.hasOwnProperty(d)?e=d:d&&S.regional.hasOwnProperty(d)&&(f=d),("[object Object]"!=D(a)||"jsDate"!=a._type)&&(a=new S(a),a.locale=f),b||(b=a.formatString||S.regional[f].formatString);for(var g,h=b||"%Y-%m-%d",i="";h.length>0;)(g=h.match(S.formats[e].codes.matcher))?(i+=h.slice(0,g.index),i+=(g[1]||"")+X(a,g[2],e),h=h.slice(g.index+g[0].length)):(i+=h,h="");return i},S.formats={ISO:"%Y-%m-%dT%H:%M:%S.%N%G",SQL:"%Y-%m-%d %H:%M:%S"},S.formats.perl={codes:{matcher:/()%(#?(%|[a-z]))/i,Y:"FullYear",y:"ShortYear.2",m:"MonthNumber.2","#m":"MonthNumber",B:"MonthName",b:"AbbrMonthName",d:"Date.2","#d":"Date",e:"Date",A:"DayName",a:"AbbrDayName",w:"Day",H:"Hours.2","#H":"Hours",I:"Hours12.2","#I":"Hours12",p:"AMPM",M:"Minutes.2","#M":"Minutes",S:"Seconds.2","#S":"Seconds",s:"Unix",N:"Milliseconds.3","#N":"Milliseconds",O:"TimezoneOffset",Z:"TimezoneName",G:"GmtOffset"},shortcuts:{F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",D:"%m/%d/%y","#c":"%a %b %e %H:%M:%S %Y",v:"%e-%b-%Y",R:"%H:%M",r:"%I:%M:%S %p",t:" ",n:"\n","%":"%"}},S.formats.php={codes:{matcher:/()%((%|[a-z]))/i,a:"AbbrDayName",A:"DayName",d:"Date.2",e:"Date",j:"DayOfYear.3",u:"DayOfWeek",w:"Day",U:"FullWeekOfYear.2",V:"IsoWeek.2",W:"WeekOfYear.2",b:"AbbrMonthName",B:"MonthName",m:"MonthNumber.2",h:"AbbrMonthName",C:"Century.2",y:"ShortYear.2",Y:"FullYear",H:"Hours.2",I:"Hours12.2",l:"Hours12",p:"AMPM",P:"AmPm",M:"Minutes.2",S:"Seconds.2",s:"Unix",O:"TimezoneOffset",z:"GmtOffset",Z:"TimezoneAbbr"},shortcuts:{D:"%m/%d/%y",F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",R:"%H:%M",r:"%I:%M:%S %p",t:" ",n:"\n","%":"%"}},S.createDate=function(a){function b(a,b){var c,d,e,f,g=parseFloat(b[1]),h=parseFloat(b[2]),i=parseFloat(b[3]),j=S.config.defaultCentury;return g>31?(d=i,e=h,c=j+g):(d=h,e=g,c=j+i),f=e+"/"+d+"/"+c,a.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/,f)}if(null==a)return new Date;if(a instanceof Date)return a;if("number"==typeof a)return new Date(a);var c=String(a).replace(/^\s*(.+)\s*$/g,"$1");c=c.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/,"$1/$2/$3"),c=c.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i,"$1 $2 $3");var d=c.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i);if(d&&d.length>3){var e=parseFloat(d[3]),f=S.config.defaultCentury+e;f=String(f),c=c.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i,d[1]+" "+d[2]+" "+f)}d=c.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/),d&&d.length>3&&(c=b(c,d));var d=c.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/);d&&d.length>3&&(c=b(c,d));for(var g,h,i,j=0,k=S.matchers.length,l=c;k>j;){if(h=Date.parse(l),!isNaN(h))return new Date(h);if(g=S.matchers[j],"function"==typeof g){if(i=g.call(S,l),i instanceof Date)return i}else l=c.replace(g[0],g[1]);j++}return NaN},S.daysInMonth=function(a,b){return 2==b?29==new Date(a,1,29).getDate()?29:28:[F,31,F,31,30,31,30,31,31,30,31,30,31][b]},S.matchers=[[/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/,"$2/$1/$3"],[/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/,"$2/$3/$1"],function(a){var b=a.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i);if(b){if(b[1]){var c=this.createDate(b[1]);if(isNaN(c))return}else{var c=new Date;c.setMilliseconds(0)}var d=parseFloat(b[2]);return b[6]&&(d="am"==b[6].toLowerCase()?12==d?0:d:12==d?12:d+12),c.setHours(d,parseInt(b[3]||0,10),parseInt(b[4]||0,10),1e3*(parseFloat(b[5]||0)||0)),c}return a},function(a){var b=a.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i);if(b){if(b[1]){var c=this.createDate(b[1]);if(isNaN(c))return}else{var c=new Date;c.setMilliseconds(0)}var d=parseFloat(b[2]);return c.setHours(d,parseInt(b[3],10),parseInt(b[4],10),1e3*parseFloat(b[5])),c}return a},function(a){var b=a.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/);if(b){var c,d,e,f=new Date,g=S.config.defaultCentury,h=parseFloat(b[1]),i=parseFloat(b[3]);h>31?(d=i,c=g+h):(d=h,c=g+i);var e=C(b[2],S.regional[S.regional.getLocale()].monthNamesShort);return-1==e&&(e=C(b[2],S.regional[S.regional.getLocale()].monthNames)),f.setFullYear(c,e,d),f.setHours(0,0,0,0),f}return a}],a.jsDate=S,a.jqplot.sprintf=function(){function b(a,b,c,d){var e=a.length>=b?"":Array(1+b-a.length>>>0).join(c);return d?a+e:e+a}function c(b){for(var c=new String(b),d=10;d>0&&c!=(c=c.replace(/^(\d+)(\d{3})/,"$1"+a.jqplot.sprintf.thousandsSeparator+"$2"));d--);return c}function d(a,c,d,e,f,g){var h=e-a.length;if(h>0){var i=" ";g&&(i=" "),a=d||!f?b(a,e,i,d):a.slice(0,c.length)+b("",h,"0",!0)+a.slice(c.length)}return a}function e(a,c,e,f,g,h,i,j){var k=a>>>0;return e=e&&k&&{2:"0b",8:"0",16:"0x"}[c]||"",a=e+b(k.toString(c),h||0,"0",!1),d(a,e,f,g,i,j)}function f(a,b,c,e,f,g){return null!=e&&(a=a.slice(0,e)),d(a,"",b,c,f,g)}var g=arguments,h=0,i=g[h++];return i.replace(a.jqplot.sprintf.regex,function(i,j,k,l,m,n,o){if("%%"==i)return"%";for(var p=!1,q="",r=!1,s=!1,t=!1,u=!1,v=0;k&&v<k.length;v++)switch(k.charAt(v)){case" ":q=" ";break;case"+":q="+";break;case"-":p=!0;break;case"0":r=!0;break;case"#":s=!0;break;case"&":t=!0;break;case"'":u=!0}if(l=l?"*"==l?+g[h++]:"*"==l.charAt(0)?+g[l.slice(1,-1)]:+l:0,0>l&&(l=-l,p=!0),!isFinite(l))throw new Error("$.jqplot.sprintf: (minimum-)width must be finite");n=n?"*"==n?+g[h++]:"*"==n.charAt(0)?+g[n.slice(1,-1)]:+n:"fFeE".indexOf(o)>-1?6:"d"==o?0:void 0;var w=j?g[j.slice(0,-1)]:g[h++];switch(o){case"s":return null==w?"":f(String(w),p,l,n,r,t);case"c":return f(String.fromCharCode(+w),p,l,n,r,t);case"b":return e(w,2,s,p,l,n,r,t);case"o":return e(w,8,s,p,l,n,r,t);case"x":return e(w,16,s,p,l,n,r,t);case"X":return e(w,16,s,p,l,n,r,t).toUpperCase();case"u":return e(w,10,s,p,l,n,r,t);case"i":var x=parseInt(+w,10);if(isNaN(x))return"";var y=0>x?"-":q,z=u?c(String(Math.abs(x))):String(Math.abs(x));return w=y+b(z,n,"0",!1),d(w,y,p,l,r,t);case"d":var x=Math.round(+w);if(isNaN(x))return"";var y=0>x?"-":q,z=u?c(String(Math.abs(x))):String(Math.abs(x));return w=y+b(z,n,"0",!1),d(w,y,p,l,r,t);case"e":case"E":case"f":case"F":case"g":case"G":var x=+w;if(isNaN(x))return"";var y=0>x?"-":q,A=["toExponential","toFixed","toPrecision"]["efg".indexOf(o.toLowerCase())],B=["toString","toUpperCase"]["eEfFgG".indexOf(o)%2],z=Math.abs(x)[A](n),C=z.toString().split(".");C[0]=u?c(C[0]):C[0],z=C.join(a.jqplot.sprintf.decimalMark),w=y+z;var D=d(w,y,p,l,r,t)[B]();return D;case"p":case"P":var x=+w;if(isNaN(x))return"";var y=0>x?"-":q,C=String(Number(Math.abs(x)).toExponential()).split(/e|E/),E=-1!=C[0].indexOf(".")?C[0].length-1:String(x).length,F=C[1]<0?-C[1]-1:0;if(Math.abs(x)<1)w=n>=E+F?y+Math.abs(x).toPrecision(E):n-1>=E?y+Math.abs(x).toExponential(E-1):y+Math.abs(x).toExponential(n-1);else{var G=n>=E?E:n;w=y+Math.abs(x).toPrecision(G)}var B=["toString","toUpperCase"]["pP".indexOf(o)%2];return d(w,y,p,l,r,t)[B]();case"n":return"";default:return i}})},a.jqplot.sprintf.thousandsSeparator=",",a.jqplot.sprintf.decimalMark=".",a.jqplot.sprintf.regex=/%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g,a.jqplot.getSignificantFigures=function(a){var b=String(Number(Math.abs(a)).toExponential()).split(/e|E/),c=-1!=b[0].indexOf(".")?b[0].length-1:b[0].length,d=b[1]<0?-b[1]-1:0,e=parseInt(b[1],10),f=e+1>0?e+1:0,g=f>=c?0:c-e-1;return{significantDigits:c,digitsLeft:f,digitsRight:g,zeros:d,exponent:e}},a.jqplot.getPrecision=function(b){return a.jqplot.getSignificantFigures(b).digitsRight};var Y=a.uiBackCompat!==!1;a.jqplot.effects={effect:{}};var Z="jqplot.storage.";a.extend(a.jqplot.effects,{version:"1.9pre",save:function(a,b){for(var c=0;c<b.length;c++)null!==b[c]&&a.data(Z+b[c],a[0].style[b[c]])},restore:function(a,b){for(var c=0;c<b.length;c++)null!==b[c]&&a.css(b[c],a.data(Z+b[c]))},setMode:function(a,b){return"toggle"===b&&(b=a.is(":hidden")?"show":"hide"),b},createWrapper:function(b){if(b.parent().is(".ui-effects-wrapper"))return b.parent();var c={width:b.outerWidth(!0),height:b.outerHeight(!0),"float":b.css("float")},d=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:b.width(),height:b.height()},f=document.activeElement;return b.wrap(d),(b[0]===f||a.contains(b[0],f))&&a(f).focus(),d=b.parent(),"static"===b.css("position")?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),b.css(e),d.css(c).show()},removeWrapper:function(b){var c=document.activeElement;return b.parent().is(".ui-effects-wrapper")&&(b.parent().replaceWith(b),(b[0]===c||a.contains(b[0],c))&&a(c).focus()),b}}),a.fn.extend({jqplotEffect:function(b,c,d,e){function f(b){function c(){a.isFunction(e)&&e.call(d[0]),a.isFunction(b)&&b()}var d=a(this),e=g.complete,f=g.mode;(d.is(":hidden")?"hide"===f:"show"===f)?c():j.call(d[0],g,c)}var g=E.apply(this,arguments),h=g.mode,i=g.queue,j=a.jqplot.effects.effect[g.effect],k=!j&&Y&&a.jqplot.effects[g.effect];return a.fx.off||!j&&!k?h?this[h](g.duration,g.complete):this.each(function(){g.complete&&g.complete.call(this)}):j?i===!1?this.each(f):this.queue(i||"fx",f):k.call(this,{options:g,duration:g.duration,callback:g.complete,mode:g.mode})}});var $=/up|down|vertical/,_=/up|left|vertical|horizontal/;a.jqplot.effects.effect.blind=function(b,c){var d,e,f,g=a(this),h=["position","top","bottom","left","right","height","width"],i=a.jqplot.effects.setMode(g,b.mode||"hide"),j=b.direction||"up",k=$.test(j),l=k?"height":"width",m=k?"top":"left",n=_.test(j),o={},p="show"===i;g.parent().is(".ui-effects-wrapper")?a.jqplot.effects.save(g.parent(),h):a.jqplot.effects.save(g,h),g.show(),f=parseInt(g.css("top"),10),d=a.jqplot.effects.createWrapper(g).css({overflow:"hidden"}),e=k?d[l]()+f:d[l](),o[l]=p?String(e):"0",n||(g.css(k?"bottom":"right",0).css(k?"top":"left","").css({position:"absolute"}),o[m]=p?"0":String(e)),p&&(d.css(l,0),n||d.css(m,e)),d.animate(o,{duration:b.duration,easing:b.easing,queue:!1,complete:function(){"hide"===i&&g.hide(),a.jqplot.effects.restore(g,h),a.jqplot.effects.removeWrapper(g),c()}})}}(jQuery);
|
js/js.js
DELETED
@@ -1,183 +0,0 @@
|
|
1 |
-
|
2 |
-
var colors = ['#DB6946', '#C14543', '#445060', '#395953', '#6C8C80', '#829AB5', '#BF807A', '#BF0000', '#006BB7', '#EC732C', '#BF3D27', '#A6375F',
|
3 |
-
'#8C6D46', '#326149', '#802B35', '#8A3842', '#366D73', '#4D6173', '#4A4659', '#C9D65B', '#F45552', '#F3CC5E', '#F29B88', '#D96941',
|
4 |
-
'#484F73', '#C9AB81', '#F5655C', '#F0C480'];
|
5 |
-
//------------------------------------------------------------------------------
|
6 |
-
function convertToNumeric(data){
|
7 |
-
if(data instanceof Array){
|
8 |
-
for(var index in data){
|
9 |
-
data[index] = Number(data[index]);
|
10 |
-
}
|
11 |
-
} else{
|
12 |
-
data = Number(data);
|
13 |
-
}
|
14 |
-
return data;
|
15 |
-
}
|
16 |
-
//------------------------------------------------------------------------------
|
17 |
-
function getRandomElementFromArray(array){
|
18 |
-
var ranIndex = Math.floor(Math.random() * array.length);
|
19 |
-
return array[ranIndex];
|
20 |
-
}
|
21 |
-
//------------------------------------------------------------------------------
|
22 |
-
function drawVisitsLineChart(visitsData){
|
23 |
-
|
24 |
-
/*
|
25 |
-
|
26 |
-
|
27 |
-
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
|
28 |
-
|
29 |
-
var barChartData = {
|
30 |
-
labels : visitsData.data.dates,
|
31 |
-
datasets : [
|
32 |
-
{
|
33 |
-
label: "Visitors",
|
34 |
-
barShowStroke: false,
|
35 |
-
fillColor : "rgba(220,220,220,0.5)",
|
36 |
-
strokeColor : "rgba(220,220,220,0.8)",
|
37 |
-
highlightFill: "rgba(220,220,220,0.75)",
|
38 |
-
highlightStroke: "rgba(220,220,220,1)",
|
39 |
-
data : visitsData.data.visitors
|
40 |
-
},
|
41 |
-
{
|
42 |
-
label: "Visits",
|
43 |
-
barShowStroke: false,
|
44 |
-
fillColor : "rgba(151,187,205,0.5)",
|
45 |
-
strokeColor : "rgba(151,187,205,0.8)",
|
46 |
-
highlightFill : "rgba(151,187,205,0.75)",
|
47 |
-
highlightStroke : "rgba(151,187,205,1)",
|
48 |
-
data : visitsData.data.visits
|
49 |
-
}
|
50 |
-
]
|
51 |
-
|
52 |
-
}
|
53 |
-
var ctx = document.getElementById("visitorsVisitsChart").getContext("2d");
|
54 |
-
window.myBar = new Chart(ctx).Bar(barChartData, {
|
55 |
-
responsive : true,
|
56 |
-
animation:true,
|
57 |
-
scaleOverride:true,
|
58 |
-
scaleSteps:5,
|
59 |
-
scaleStartValue:0,
|
60 |
-
scaleStepWidth:10
|
61 |
-
});
|
62 |
-
*/
|
63 |
-
|
64 |
-
|
65 |
-
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
|
66 |
-
var lineChartData = {
|
67 |
-
labels : visitsData.data.dates,
|
68 |
-
datasets : [
|
69 |
-
{
|
70 |
-
label: "Visitors",
|
71 |
-
fillColor : "rgba(220,220,220,0.2)",
|
72 |
-
strokeColor : "rgba(220,220,220,1)",
|
73 |
-
pointColor : "rgba(220,220,220,1)",
|
74 |
-
pointStrokeColor : "#fff",
|
75 |
-
pointHighlightFill : "#fff",
|
76 |
-
pointHighlightStroke : "rgba(220,220,220,1)",
|
77 |
-
data : visitsData.data.visitors
|
78 |
-
},
|
79 |
-
{
|
80 |
-
label: "Visits",
|
81 |
-
fillColor : "rgba(151,187,205,0.2)",
|
82 |
-
strokeColor : "rgba(151,187,205,1)",
|
83 |
-
pointColor : "rgba(151,187,205,1)",
|
84 |
-
pointStrokeColor : "#fff",
|
85 |
-
pointHighlightFill : "#fff",
|
86 |
-
pointHighlightStroke : "rgba(151,187,205,1)",
|
87 |
-
data : visitsData.data.visits
|
88 |
-
}
|
89 |
-
]
|
90 |
-
|
91 |
-
}
|
92 |
-
|
93 |
-
window.onload = function(){
|
94 |
-
var ctx = document.getElementById("visitorsVisitsChart").getContext("2d");
|
95 |
-
window.myLine = new Chart(ctx).Line(lineChartData, {
|
96 |
-
responsive: true,
|
97 |
-
scaleOverride:false,
|
98 |
-
scaleSteps:5,
|
99 |
-
scaleStartValue:0,
|
100 |
-
scaleStepWidth:5
|
101 |
-
});
|
102 |
-
}
|
103 |
-
|
104 |
-
}
|
105 |
-
//------------------------------------------------------------------------------
|
106 |
-
function drawBrowsersBieChart(browsersData){
|
107 |
-
var brsBieChartData = [];
|
108 |
-
var container = jQuery('#browsersLegContainer');
|
109 |
-
var html = '';
|
110 |
-
if(browsersData.length == 0)
|
111 |
-
{
|
112 |
-
document.getElementById('browsersLegContainer').style.display = 'none';
|
113 |
-
}else{
|
114 |
-
document.getElementById('browsersLegContainer').style.display = 'block';
|
115 |
-
}
|
116 |
-
for(var i = 0; i < browsersData.length; i++){
|
117 |
-
var color = getRandomElementFromArray(colors);
|
118 |
-
var value = Number(browsersData[i].hits);
|
119 |
-
brsBieChartData[i] = {label: browsersData[i].bsr_name, value: value, color: color};
|
120 |
-
html += (isEmpty(value))? '' : '<div class="legend">' +
|
121 |
-
'<span class="color" style="background-color: ' + color + ';"> </span>' +
|
122 |
-
'<span class="name">' + browsersData[i].bsr_name + '</span>' +
|
123 |
-
'<span class="value">' + value + '</span>' +
|
124 |
-
'</div>';
|
125 |
-
}
|
126 |
-
html += '<div class="cleaner"></div>';
|
127 |
-
container.html(html);
|
128 |
-
var ctx = document.getElementById("brsBiechartContainer").getContext("2d");
|
129 |
-
window.myPie = new Chart(ctx).Pie(brsBieChartData);
|
130 |
-
}
|
131 |
-
//------------------------------------------------------------------------------
|
132 |
-
function drawSrhEngVstLineChart(srhEngVisitsData){
|
133 |
-
var srh_series = [];
|
134 |
-
var container = jQuery('#srchEngLegContainer');
|
135 |
-
|
136 |
-
document.getElementById('srchEngLegContainer').style.display = 'none';
|
137 |
-
var html = '';
|
138 |
-
for(var index in srhEngVisitsData.data.search_engines){
|
139 |
-
var color = getRandomElementFromArray(colors);
|
140 |
-
var value = countVisits(srhEngVisitsData.data.search_engines[index]);
|
141 |
-
|
142 |
-
if(parseFloat(value) !=0)
|
143 |
-
{
|
144 |
-
document.getElementById('srchEngLegContainer').style.display = 'block';
|
145 |
-
}
|
146 |
-
|
147 |
-
srh_series[srh_series.length] = {
|
148 |
-
"label": index,
|
149 |
-
"value": value,
|
150 |
-
"color": color
|
151 |
-
}
|
152 |
-
|
153 |
-
html += (isEmpty(value))? '' : '<div class="legend">' +
|
154 |
-
'<span class="color" style="background-color: ' + color + ';"> </span>' +
|
155 |
-
'<span class="name">' + index + '</span>' +
|
156 |
-
'<span class="value">' + value + '</span>' +
|
157 |
-
'</div>';
|
158 |
-
}
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
html += '<div class="cleaner"></div>';
|
164 |
-
container.html(html);
|
165 |
-
var ctx = document.getElementById("srhEngBieChartContainer").getContext("2d");
|
166 |
-
window.myPie = new Chart(ctx).Pie(srh_series);
|
167 |
-
}
|
168 |
-
|
169 |
-
function isEmpty(val){
|
170 |
-
return (val == null || val == 0 || val == '' || val == '0');
|
171 |
-
}
|
172 |
-
|
173 |
-
//------------------------------------------------------------------------------
|
174 |
-
function countVisits(arr){
|
175 |
-
var count = 0;
|
176 |
-
for(var i = 0; i < arr.length; i++){
|
177 |
-
count += Number(arr[i]);
|
178 |
-
}
|
179 |
-
return count;
|
180 |
-
}
|
181 |
-
//------------------------------------------------------------------------------
|
182 |
-
|
183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/sweetalert.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Sweetalert2=t()}(this,function(){"use strict";function e(){if(void 0===arguments[0])return console.error("SweetAlert2 expects at least 1 attribute!"),!1;var e=c({},j);switch(typeof arguments[0]){case"string":e.title=arguments[0],e.text=arguments[1]||"",e.type=arguments[2]||"";break;case"object":c(e,arguments[0]),e.extraParams=arguments[0].extraParams,"email"===e.input&&null===e.inputValidator&&(e.inputValidator=function(e){return new Promise(function(t,n){var o=/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;o.test(e)?t():n("Invalid email address")})});break;default:return console.error('SweetAlert2: Unexpected type of argument! Expected "string" or "object", got '+typeof arguments[0]),!1}K(e);var n=f();return new Promise(function(o,r){function a(t,n){for(var o=b(e.focusCancel),i=0;i<o.length;i++){t+=n,t===o.length?t=0:-1===t&&(t=o.length-1);var r=o[t];if(L(r))return r.focus()}}function l(n){var o=n||window.event,i=o.keyCode||o.which;if(-1!==[9,13,32,27].indexOf(i)){for(var l=o.target||o.srcElement,c=b(e.focusCancel),s=-1,u=0;u<c.length;u++)if(l===c[u]){s=u;break}9===i?(o.shiftKey?a(s,-1):a(s,1),V(o)):13===i||32===i?-1===s&&(e.focusCancel?O(P,o):O(M,o)):27===i&&e.allowEscapeKey===!0&&(t.closeModal(e.onClose),r("esc"))}}e.timer&&(n.timeout=setTimeout(function(){t.closeModal(e.onClose),r("timer")},e.timer));var c=function(){switch(e.input){case"select":return x(n,i.select);case"radio":return n.querySelector("."+i.radio+" input:checked")||n.querySelector("."+i.radio+" input:first-child");case"checkbox":return n.querySelector("#"+i.checkbox);case"textarea":return x(n,i.textarea);default:return x(n,i.input)}},u=function(){var t=c();switch(e.input){case"checkbox":return t.checked?1:0;case"radio":return t.checked?t.value:null;case"file":return t.files.length?t.files[0]:null;default:return e.inputAutoTrim?t.value.trim():t.value}};e.input&&setTimeout(function(){var e=c();e&&w(e)},0);var p,f=function(n){e.showLoaderOnConfirm&&t.showLoading(),e.preConfirm?e.preConfirm(n,e.extraParams).then(function(i){t.closeModal(e.onClose),o(i||n)},function(e){t.hideLoading(),e&&t.showValidationError(e)}):(t.closeModal(e.onClose),o(n))},g=function(n){var o=n||window.event,i=o.target||o.srcElement,a=v(),l=h(),c=a===i||a.contains(i),d=l===i||l.contains(i);switch(o.type){case"mouseover":case"mouseup":e.buttonsStyling&&(c?a.style.backgroundColor=s(e.confirmButtonColor,-.1):d&&(l.style.backgroundColor=s(e.cancelButtonColor,-.1)));break;case"mouseout":e.buttonsStyling&&(c?a.style.backgroundColor=e.confirmButtonColor:d&&(l.style.backgroundColor=e.cancelButtonColor));break;case"mousedown":e.buttonsStyling&&(c?a.style.backgroundColor=s(e.confirmButtonColor,-.2):d&&(l.style.backgroundColor=s(e.cancelButtonColor,-.2)));break;case"click":if(c&&t.isVisible())if(e.input){var p=u();e.inputValidator?(t.disableInput(),e.inputValidator(p,e.extraParams).then(function(){t.enableInput(),f(p)},function(e){t.enableInput(),e&&t.showValidationError(e)})):f(p)}else f(!0);else d&&t.isVisible()&&(t.closeModal(e.onClose),r("cancel"))}},q=n.querySelectorAll("button");for(p=0;p<q.length;p++)q[p].onclick=g,q[p].onmouseover=g,q[p].onmouseout=g,q[p].onmousedown=g;y().onclick=function(){t.closeModal(e.onClose),r("close")},m().onclick=function(){e.allowOutsideClick&&(t.closeModal(e.onClose),r("overlay"))};var M=v(),P=h();e.reverseButtons?M.parentNode.insertBefore(P,M):M.parentNode.insertBefore(M,P),d.previousWindowKeyDown=window.onkeydown,window.onkeydown=l,e.buttonsStyling&&(M.style.borderLeftColor=e.confirmButtonColor,M.style.borderRightColor=e.confirmButtonColor),t.showLoading=t.enableLoading=function(){C(M,"loading"),C(n,"loading"),M.disabled=!0,P.disabled=!0},t.hideLoading=t.disableLoading=function(){k(M,"loading"),k(n,"loading"),M.disabled=!1,P.disabled=!1},t.enableButtons=function(){M.disabled=!1,P.disabled=!1},t.disableButtons=function(){M.disabled=!0,P.disabled=!0},t.enableConfirmButton=function(){M.disabled=!1},t.disableConfirmButton=function(){M.disabled=!0},t.enableInput=function(){var e=c();if("radio"===e.type)for(var t=e.parentNode.parentNode,n=t.querySelectorAll("input"),o=0;o<n.length;o++)n[o].disabled=!1;else e.disabled=!1},t.disableInput=function(){var e=c();if("radio"===e.type)for(var t=e.parentNode.parentNode,n=t.querySelectorAll("input"),o=0;o<n.length;o++)n[o].disabled=!0;else e.disabled=!0},t.showValidationError=function(e){var t=n.querySelector("."+i.validationerror);t.innerHTML=e,S(t);var o=c();w(o),C(o,"error")},t.resetValidationError=function(){var e=n.querySelector("."+i.validationerror);B(e);var t=c();t&&k(t,"error")},t.enableButtons(),t.hideLoading(),t.resetValidationError();var T,N=["input","select","radio","checkbox","textarea"];for(p=0;p<N.length;p++){var H=i[N[p]];for(T=x(n,H);T.attributes.length>0;)T.removeAttribute(T.attributes[0].name);for(var D in e.inputAttributes)T.setAttribute(D,e.inputAttributes[D]);T.className=H,e.inputClass&&C(T,e.inputClass),A(T)}var I;switch(e.input){case"text":case"email":case"password":case"file":T=x(n,i.input),T.value=e.inputValue,T.placeholder=e.inputPlaceholder,T.type=e.input,E(T);break;case"select":var j=x(n,i.select);if(j.innerHTML="",e.inputPlaceholder){var K=document.createElement("option");K.innerHTML=e.inputPlaceholder,K.value="",K.disabled=!0,K.selected=!0,j.appendChild(K)}I=function(t){for(var n in t){var o=document.createElement("option");o.value=n,o.innerHTML=t[n],e.inputValue===n&&(o.selected=!0),j.appendChild(o)}E(j),j.focus()};break;case"radio":var z=x(n,i.radio);z.innerHTML="",I=function(t){for(var n in t){var o=1,r=document.createElement("input"),a=document.createElement("label"),l=document.createElement("span");r.type="radio",r.name=i.radio,r.value=n,r.id=i.radio+"-"+o++,e.inputValue===n&&(r.checked=!0),l.innerHTML=t[n],a.appendChild(r),a.appendChild(l),a["for"]=r.id,z.appendChild(a)}E(z);var c=z.querySelectorAll("input");c.length&&c[0].focus()};break;case"checkbox":var R=x(n,i.checkbox),Z=n.querySelector("#"+i.checkbox);Z.value=1,Z.checked=Boolean(e.inputValue);var $=R.getElementsByTagName("span");$.length&&R.removeChild($[0]),$=document.createElement("span"),$.innerHTML=e.inputPlaceholder,R.appendChild($),E(R);break;case"textarea":var F=x(n,i.textarea);F.value=e.inputValue,F.placeholder=e.inputPlaceholder,E(F);break;case null:break;default:console.error('SweetAlert2: Unexpected type of input! Expected "text" or "email" or "password", "select", "checkbox", "textarea" or "file", got "'+e.input+'"')}"select"!==e.input&&"radio"!==e.input||(e.inputOptions instanceof Promise?(t.showLoading(),e.inputOptions.then(function(e){t.hideLoading(),I(e)})):"object"==typeof e.inputOptions?I(e.inputOptions):console.error("SweetAlert2: Unexpected type of inputOptions! Expected object or Promise, got "+typeof e.inputOptions)),W(),U(e.animation,e.onOpen),a(-1,1)})}function t(){var n=arguments,o=f();return null===o&&(t.init(),o=f()),t.isVisible()&&t.close(),e.apply(this,n)}var n="swal2-",o=function(e){var t={};for(var o in e)t[e[o]]=n+e[o];return t},i=o(["container","modal","overlay","close","content","spacer","confirm","cancel","icon","image","input","select","radio","checkbox","textarea","validationerror"]),r=o(["success","warning","info","question","error"]),a={title:"",text:"",html:"",type:null,customClass:"",animation:!0,allowOutsideClick:!0,allowEscapeKey:!0,showConfirmButton:!0,showCancelButton:!1,preConfirm:null,confirmButtonText:"OK",confirmButtonColor:"#3085d6",confirmButtonClass:null,cancelButtonText:"Cancel",cancelButtonColor:"#aaa",cancelButtonClass:null,buttonsStyling:!0,reverseButtons:!1,focusCancel:!1,showCloseButton:!1,showLoaderOnConfirm:!1,imageUrl:null,imageWidth:null,imageHeight:null,imageClass:null,timer:null,width:500,padding:20,background:"#fff",input:null,inputPlaceholder:"",inputValue:"",inputOptions:{},inputAutoTrim:!0,inputClass:null,inputAttributes:{},inputValidator:null,onOpen:null,onClose:null},l='<div class="'+i.overlay+'" tabIndex="-1"></div><div class="'+i.modal+'" style="display: none" tabIndex="-1"><div class="'+i.icon+" "+r.error+'"><span class="x-mark"><span class="line left"></span><span class="line right"></span></span></div><div class="'+i.icon+" "+r.question+'">?</div><div class="'+i.icon+" "+r.warning+'">!</div><div class="'+i.icon+" "+r.info+'">i</div><div class="'+i.icon+" "+r.success+'"><span class="line tip"></span> <span class="line long"></span><div class="placeholder"></div> <div class="fix"></div></div><img class="'+i.image+'"><h2></h2><div class="'+i.content+'"></div><input class="'+i.input+'"><select class="'+i.select+'"></select><div class="'+i.radio+'"></div><label for="'+i.checkbox+'" class="'+i.checkbox+'"><input type="checkbox" id="'+i.checkbox+'"></label><textarea class="'+i.textarea+'"></textarea><div class="'+i.validationerror+'"></div><hr class="'+i.spacer+'"><button class="'+i.confirm+'">OK</button><button class="'+i.cancel+'">Cancel</button><span class="'+i.close+'">×</span></div>',c=function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},s=function(e,t){e=String(e).replace(/[^0-9a-f]/gi,""),e.length<6&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),t=t||0;for(var n="#",o=0;3>o;o++){var i=parseInt(e.substr(2*o,2),16);i=Math.round(Math.min(Math.max(0,i+i*t),255)).toString(16),n+=("00"+i).substr(i.length)}return n},u=function(e){return"function"==typeof e},d={previousWindowKeyDown:null,previousActiveElement:null},p=function(e){return document.querySelector("."+e)},f=function(){return p(i.modal)},m=function(){return p(i.overlay)},v=function(){return p(i.confirm)},h=function(){return p(i.cancel)},y=function(){return p(i.close)},b=function(e){var t=[v(),h()];return e&&t.reverse(),t.concat(Array.prototype.slice.call(f().querySelectorAll("button:not([class^="+n+"]), input:not([type=hidden]), textarea, select")))},g=function(e,t){return e.classList.contains(t)},w=function(e){e.focus();var t=e.value;e.value="",e.value=t},C=function(e,t){if(e&&t){var n=t.split(/\s+/);n.forEach(function(t){e.classList.add(t)})}},k=function(e,t){if(e&&t){var n=t.split(/\s+/);n.forEach(function(t){e.classList.remove(t)})}},x=function(e,t){for(var n=0;n<e.childNodes.length;n++)if(g(e.childNodes[n],t))return e.childNodes[n]},E=function(e){e.style.opacity="",e.style.display="block"},S=function(e){if(e&&!e.length)return E(e);for(var t=0;t<e.length;++t)E(e[t])},A=function(e){e.style.opacity="",e.style.display="none"},B=function(e){if(e&&!e.length)return A(e);for(var t=0;t<e.length;++t)A(e[t])},L=function(e){return e.offsetWidth||e.offsetHeight||e.getClientRects().length},q=function(e,t){e.style.removeProperty?e.style.removeProperty(t):e.style.removeAttribute(t)},M=function(e){var t=e.style.display;e.style.left="-9999px",e.style.display="block";var n=e.clientHeight;return e.style.left="",e.style.display=t,"-"+parseInt(n/2,10)+"px"},P=function(e,t){if(+e.style.opacity<1){t=t||16,e.style.opacity=0,e.style.display="block";var n=+new Date,o=function(){var i=+e.style.opacity+(new Date-n)/100;e.style.opacity=i>1?1:i,n=+new Date,+e.style.opacity<1&&setTimeout(o,t)};o()}},T=function(e,t){if(+e.style.opacity>0){t=t||16;var n=e.style.opacity,o=+new Date,i=function(){var r=new Date-o,a=+e.style.opacity-r/(100*n);e.style.opacity=a,o=+new Date,+e.style.opacity>0?setTimeout(i,t):A(e)};i()}},O=function(e){if("function"==typeof MouseEvent){var t=new MouseEvent("click",{view:window,bubbles:!1,cancelable:!0});e.dispatchEvent(t)}else if(document.createEvent){var n=document.createEvent("MouseEvents");n.initEvent("click",!1,!1),e.dispatchEvent(n)}else document.createEventObject?e.fireEvent("onclick"):"function"==typeof e.onclick&&e.onclick()},V=function(e){"function"==typeof e.stopPropagation?(e.stopPropagation(),e.preventDefault()):window.event&&window.event.hasOwnProperty("cancelBubble")&&(window.event.cancelBubble=!0)},N=function(){var e=document.createElement("div"),t={WebkitAnimation:"webkitAnimationEnd",OAnimation:"oAnimationEnd oanimationend",msAnimation:"MSAnimationEnd",animation:"animationend"};for(var n in t)if(t.hasOwnProperty(n)&&void 0!==e.style[n])return t[n];return!1}(),H=function(){var e=f();window.onkeydown=d.previousWindowKeyDown,d.previousActiveElement&&d.previousActiveElement.focus&&d.previousActiveElement.focus(),clearTimeout(e.timeout)},D=function(e){var t=n+"mediaquery-"+Math.random().toString(36).substring(2,7),o=document.getElementsByTagName("head")[0],i=document.createElement("style");return i.type="text/css",i.id=t,i.innerHTML=e,o.appendChild(i),t},I=function(e){if(!e)return!1;var t=document.getElementsByTagName("head")[0],n=document.getElementById(e);n&&t.removeChild(n)},j=c({},a),K=function(e){var t=f();for(var n in e)a.hasOwnProperty(n)||"extraParams"===n||console.warn('SweetAlert2: Unknown parameter "'+n+'"');e.width=e.width.toString();var o,l=e.width.match(/^(\d+)(px|%)?$/);if(l?(o="px",l[2]&&(o=l[2]),l=parseInt(l[1],10),t.style.width=l+o,t.style.marginLeft=-l/2+o):console.warn('SweetAlert2: Invalid width parameter, usage examples: "400px", "50%", or just 500 which equals to "500px"'),t.style.padding=e.padding+"px",t.style.background=e.background,"px"===o){var c=5,s=l+l*(c/100)*2,u=D("@media screen and (max-width: "+s+"px) {."+i.modal+" {width: auto !important;left: "+c+"% !important;right: "+c+"% !important;margin-left: 0 !important;}}");t.setAttribute("data-mediaquery-id",u)}var d=t.querySelector("h2"),p=t.querySelector("."+i.content),m=v(),y=h(),b=t.querySelector("."+i.spacer),g=t.querySelector("."+i.close);if(d.innerHTML=e.title.split("\n").join("<br>"),e.text||e.html){if("object"==typeof e.html)if(p.innerHTML="",0 in e.html)for(var w=0;w in e.html;w++)p.appendChild(e.html[w]);else p.appendChild(e.html);else p.innerHTML=e.html||e.text.split("\n").join("<br>");S(p)}else B(p);if(e.showCloseButton?S(g):B(g),t.className=i.modal,e.customClass&&C(t,e.customClass),B(t.querySelectorAll("."+i.icon)),e.type){var x=!1;for(var E in r)if(e.type===E){x=!0;break}if(!x)return console.error("SweetAlert2: Unknown alert type: "+e.type),!1;var A=t.querySelector("."+i.icon+"."+r[e.type]);switch(S(A),e.type){case"success":C(A,"animate"),C(A.querySelector(".tip"),"animate-success-tip"),C(A.querySelector(".long"),"animate-success-long");break;case"error":C(A,"animate-error-icon"),C(A.querySelector(".x-mark"),"animate-x-mark");break;case"warning":C(A,"pulse-warning")}}var L=t.querySelector("."+i.image);e.imageUrl?(L.setAttribute("src",e.imageUrl),S(L),e.imageWidth?L.setAttribute("width",e.imageWidth):L.removeAttribute("width"),e.imageHeight?L.setAttribute("height",e.imageHeight):L.removeAttribute("height"),L.className=i.image,e.imageClass&&C(L,e.imageClass)):B(L),e.showCancelButton?y.style.display="inline-block":B(y),e.showConfirmButton?q(m,"display"):B(m),e.showConfirmButton||e.showCancelButton?S(b):B(b),m.innerHTML=e.confirmButtonText,y.innerHTML=e.cancelButtonText,e.buttonsStyling&&(m.style.backgroundColor=e.confirmButtonColor,y.style.backgroundColor=e.cancelButtonColor),m.className=i.confirm,C(m,e.confirmButtonClass),y.className=i.cancel,C(y,e.cancelButtonClass),e.buttonsStyling?(C(m,"styled"),C(y,"styled")):(k(m,"styled"),k(y,"styled"),m.style.backgroundColor=m.style.borderLeftColor=m.style.borderRightColor="",y.style.backgroundColor=y.style.borderLeftColor=y.style.borderRightColor=""),e.animation===!0?k(t,"no-animation"):C(t,"no-animation")},U=function(e,t){var n=f();e?(P(m(),10),C(n,"show-swal2"),k(n,"hide-swal2")):S(m()),S(n),d.previousActiveElement=document.activeElement,null!==t&&"function"==typeof t&&t.call(this,n)},W=function(){var e=f();null!==e&&(e.style.marginTop=M(e))};return t.isVisible=function(){var e=f();return L(e)},t.queue=function(e,n){var o;return n&&(o={fork:function(e){n=e,this.next=e[0]},repeatCurrent:function(){n.unshift(this.current),this.next=this.current},insert:function(e){n.unshift(e),this.next=this.state},terminate:function(){n=[],this.next=""}}),new Promise(function(i,r){!function a(l,c){var s=null;u(e)?n&&n.length>0?(o.current=n[0],o.next=n.length>1?n[1]:"",o.alertNumber=l,n.shift(),s=e(o)):s=e(l):l<e.length&&(s=e[l]),s?t(s).then(function(){a(l+1,c)},function(e){r(e)}):i()}(0)})},t.close=t.closeModal=function(e){var t=f();k(t,"show-swal2"),C(t,"hide-swal2");var n=t.querySelector("."+i.icon+"."+r.success);k(n,"animate"),k(n.querySelector(".tip"),"animate-success-tip"),k(n.querySelector(".long"),"animate-success-long");var o=t.querySelector("."+i.icon+"."+r.error);k(o,"animate-error-icon"),k(o.querySelector(".x-mark"),"animate-x-mark");var a=t.querySelector("."+i.icon+"."+r.warning);k(a,"pulse-warning"),H();var l=t.getAttribute("data-mediaquery-id");N&&!g(t,"no-animation")?t.addEventListener(N,function c(){t.removeEventListener(N,c),g(t,"hide-swal2")&&(A(t),T(m(),0)),I(l)}):(A(t),A(m()),I(l)),null!==e&&"function"==typeof e&&e.call(this,t)},t.clickConfirm=function(){v().click()},t.clickCancel=function(){h().click()},t.init=function(){if("undefined"==typeof document)return void console.log("SweetAlert2 requires document to initialize");if(!document.getElementsByClassName(i.container).length){var e=document.createElement("div");e.className=i.container,e.innerHTML=l,document.body.appendChild(e);var n=f(),o=x(n,i.input),r=x(n,i.select),a=n.querySelector("#"+i.checkbox),c=x(n,i.textarea),s=x(n,i.image);o.oninput=function(){t.resetValidationError()},o.onkeyup=function(e){e.stopPropagation(),13===e.keyCode&&t.clickConfirm()},r.onchange=function(){t.resetValidationError()},a.onchange=function(){t.resetValidationError()},c.oninput=function(){t.resetValidationError()},s.onload=s.onerror=W,window.addEventListener("resize",W,!1)}},t.setDefaults=function(e){if(!e)throw new Error("userParams is required");if("object"!=typeof e)throw new Error("userParams has to be a object");c(j,e)},t.resetDefaults=function(){j=c({},a)},t.version="4.2.4",window.sweetAlert=window.swal=t,function(){"complete"===document.readyState||"interactive"===document.readyState&&document.body?t.init():document.addEventListener("DOMContentLoaded",function e(){document.removeEventListener("DOMContentLoaded",e,!1),t.init()},!1)}(),"function"==typeof Promise?Promise.prototype.done=Promise.prototype.done||function(){return this["catch"](function(){})}:console.warn("SweetAlert2: Please inlude Promise polyfill BEFORE including sweetalert2.js if IE10+ support needed."),t});
|
lang/ar_lang.php
CHANGED
@@ -1,48 +1,48 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
define('
|
4 |
define('ahc_visitors', 'الزوار');
|
5 |
-
define('
|
6 |
-
define('
|
7 |
-
define('
|
8 |
-
define('
|
9 |
-
define('
|
10 |
-
define('
|
11 |
-
define('
|
12 |
|
13 |
define('ahc_search_engines', 'محركات البحث');
|
14 |
-
define('
|
15 |
|
16 |
define('ahc_browsers', 'المتصفحات');
|
17 |
|
18 |
define('ahc_refering_sites', 'أكثر المواقع المشيرة للموقع');
|
19 |
-
define('
|
20 |
-
define('
|
21 |
|
22 |
define('ahc_countries_visits_rank', 'ترتيب الدول حسب الزوار');
|
23 |
-
define('
|
24 |
-
define('
|
25 |
-
define('
|
26 |
|
27 |
define('ahc_recent_visitors', 'اخر الزوار');
|
28 |
|
29 |
-
define('
|
30 |
|
31 |
-
define('
|
32 |
|
33 |
-
define('
|
34 |
-
define('
|
35 |
define('ahc_search_engines_in_last_20days', 'محركات البحث بالنسبة للزيارات في اخر 20 يوم');
|
36 |
|
37 |
define('traffic_by_title', 'الزيارات بالنسبة للمواضيع');
|
38 |
-
define('
|
39 |
define('ahc_hits', 'المشاهدات');
|
40 |
-
define('
|
41 |
|
42 |
define('ahc_visits_time_graph', 'أوقات الزيارات');
|
43 |
-
define('
|
44 |
define('ahc_visitors_graph', 'الزوار');
|
45 |
-
define('
|
46 |
|
47 |
-
define('
|
48 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
define('ahcfree_summary_statistics', 'إحصائية موجزة');
|
4 |
define('ahc_visitors', 'الزوار');
|
5 |
+
define('ahcfree_visits', 'المشاهدات');
|
6 |
+
define('ahcfree_today', 'اليوم');
|
7 |
+
define('ahcfree_yesterday', 'الأمس');
|
8 |
+
define('ahcfree_this_week', 'هذ الأسبوع');
|
9 |
+
define('ahcfree_this_month', 'هذا الشهر');
|
10 |
+
define('ahcfree_this_yesr', 'هذا العام');
|
11 |
+
define('ahcfree_total', 'المجموع');
|
12 |
|
13 |
define('ahc_search_engines', 'محركات البحث');
|
14 |
+
define('ahcfree_daily_total', 'المجموع اليومي');
|
15 |
|
16 |
define('ahc_browsers', 'المتصفحات');
|
17 |
|
18 |
define('ahc_refering_sites', 'أكثر المواقع المشيرة للموقع');
|
19 |
+
define('ahcfree_total_times', 'عدد المرات');
|
20 |
+
define('ahcfree_site_name', 'إسم الموقع');
|
21 |
|
22 |
define('ahc_countries_visits_rank', 'ترتيب الدول حسب الزوار');
|
23 |
+
define('ahcfree_country', 'الدولة');
|
24 |
+
define('ahcfree_rank', 'الترتيب');
|
25 |
+
define('ahcfree_flag', 'العلم');
|
26 |
|
27 |
define('ahc_recent_visitors', 'اخر الزوار');
|
28 |
|
29 |
+
define('ahcfree_latest_search_words', 'أخر الكلمات المستخدمة في البحث');
|
30 |
|
31 |
+
define('ahcfree_today_visitors_on_map', 'زوار اليوم على الخريطة');
|
32 |
|
33 |
+
define('ahcfree_visits_in_last_20days', 'المشاهدات في اخر '.AHC_VISITORS_VISITS_LIMIT.' يوم');
|
34 |
+
define('ahcfree_no_visits_visitors', 'عدد الزوار والزيارات');
|
35 |
define('ahc_search_engines_in_last_20days', 'محركات البحث بالنسبة للزيارات في اخر 20 يوم');
|
36 |
|
37 |
define('traffic_by_title', 'الزيارات بالنسبة للمواضيع');
|
38 |
+
define('ahcfree_title', 'العنوان');
|
39 |
define('ahc_hits', 'المشاهدات');
|
40 |
+
define('ahcfree_percent', 'النسبة');
|
41 |
|
42 |
define('ahc_visits_time_graph', 'أوقات الزيارات');
|
43 |
+
define('ahcfree_time', 'الوقت');
|
44 |
define('ahc_visitors_graph', 'الزوار');
|
45 |
+
define('ahcfree_pages', 'الصفجات');
|
46 |
|
47 |
+
define('ahcfree_view_referer', 'عرض الرابط المشير');
|
48 |
?>
|
lang/en_lang.php
CHANGED
@@ -1,48 +1,48 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
define('
|
4 |
define('ahc_visitors', 'Visitors');
|
5 |
-
define('
|
6 |
-
define('
|
7 |
-
define('
|
8 |
-
define('
|
9 |
-
define('
|
10 |
-
define('
|
11 |
-
define('
|
12 |
|
13 |
define('ahc_search_engines', 'Search Engines');
|
14 |
-
define('
|
15 |
|
16 |
define('ahc_browsers', 'Browsers');
|
17 |
|
18 |
define('ahc_refering_sites', 'Top Refering Sites');
|
19 |
-
define('
|
20 |
-
define('
|
21 |
|
22 |
define('ahc_countries_visits_rank', 'Countries Rank in Order to Visitors');
|
23 |
-
define('
|
24 |
-
define('
|
25 |
-
define('
|
26 |
|
27 |
define('ahc_recent_visitors', 'Recent Visitors');
|
28 |
|
29 |
-
define('
|
30 |
|
31 |
-
define('
|
32 |
|
33 |
-
define('
|
34 |
-
define('
|
35 |
define('ahc_search_engines_in_last_20days', 'Referrer search engine in the last 20 days');
|
36 |
|
37 |
define('traffic_by_title', 'Traffic by title');
|
38 |
-
define('
|
39 |
define('ahc_hits', 'Hits');
|
40 |
-
define('
|
41 |
|
42 |
define('ahc_visits_time_graph', 'Visits time graph');
|
43 |
-
define('
|
44 |
define('ahc_visitors_graph', 'Visitors graph');
|
45 |
-
define('
|
46 |
|
47 |
-
define('
|
48 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
define('ahcfree_summary_statistics', 'Summary Statistics');
|
4 |
define('ahc_visitors', 'Visitors');
|
5 |
+
define('ahcfree_visits', 'Visits');
|
6 |
+
define('ahcfree_today', 'Today');
|
7 |
+
define('ahcfree_yesterday', 'Yesterday');
|
8 |
+
define('ahcfree_this_week', 'This Week');
|
9 |
+
define('ahcfree_this_month', 'This Month');
|
10 |
+
define('ahcfree_this_yesr', 'This Year');
|
11 |
+
define('ahcfree_total', 'Total');
|
12 |
|
13 |
define('ahc_search_engines', 'Search Engines');
|
14 |
+
define('ahcfree_daily_total', 'Daily Total');
|
15 |
|
16 |
define('ahc_browsers', 'Browsers');
|
17 |
|
18 |
define('ahc_refering_sites', 'Top Refering Sites');
|
19 |
+
define('ahcfree_total_times', 'Total Times');
|
20 |
+
define('ahcfree_site_name', 'Site Name');
|
21 |
|
22 |
define('ahc_countries_visits_rank', 'Countries Rank in Order to Visitors');
|
23 |
+
define('ahcfree_country', 'Country');
|
24 |
+
define('ahcfree_rank', 'Rank');
|
25 |
+
define('ahcfree_flag', 'Flag');
|
26 |
|
27 |
define('ahc_recent_visitors', 'Recent Visitors');
|
28 |
|
29 |
+
define('ahcfree_latest_search_words', 'Latest Search Words');
|
30 |
|
31 |
+
define('ahcfree_today_visitors_on_map', 'Today Visitors on Map');
|
32 |
|
33 |
+
define('ahcfree_visits_in_last_20days', 'Visits in the last '.AHC_VISITORS_VISITS_LIMIT.' days');
|
34 |
+
define('ahcfree_no_visits_visitors', 'Number of visitors and visits');
|
35 |
define('ahc_search_engines_in_last_20days', 'Referrer search engine in the last 20 days');
|
36 |
|
37 |
define('traffic_by_title', 'Traffic by title');
|
38 |
+
define('ahcfree_title', 'Title');
|
39 |
define('ahc_hits', 'Hits');
|
40 |
+
define('ahcfree_percent', 'Percent');
|
41 |
|
42 |
define('ahc_visits_time_graph', 'Visits time graph');
|
43 |
+
define('ahcfree_time', 'Time');
|
44 |
define('ahc_visitors_graph', 'Visitors graph');
|
45 |
+
define('ahcfree_pages', 'Pages');
|
46 |
|
47 |
+
define('ahcfree_view_referer', 'View referer link');
|
48 |
?>
|
lang/js/ar_lang.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
|
2 |
var ahc_visitors = 'الزوار';
|
3 |
-
var
|
4 |
-
var
|
5 |
-
var
|
1 |
|
2 |
var ahc_visitors = 'الزوار';
|
3 |
+
var ahcfree_visits = 'المشاهدات';
|
4 |
+
var ahcfree_no_visits_visitors = 'عدد الزوار والزيارات';
|
5 |
+
var ahcfree_no_visits = 'عدد الزيارات';
|
lang/js/en_lang.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
|
2 |
var ahc_visitors = 'Visitors';
|
3 |
-
var
|
4 |
-
var
|
5 |
-
var
|
1 |
|
2 |
var ahc_visitors = 'Visitors';
|
3 |
+
var ahcfree_visits = 'Visits';
|
4 |
+
var ahcfree_no_visits_visitors = 'Number of visitors and visits';
|
5 |
+
var ahcfree_no_visits = 'Number of visits';
|
lib/Chart_js/.gitignore
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
|
2 |
-
.DS_Store
|
3 |
-
|
4 |
-
node_modules/*
|
5 |
-
custom/*
|
6 |
-
|
7 |
-
docs/index.md
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/CONTRIBUTING.md
DELETED
@@ -1,20 +0,0 @@
|
|
1 |
-
Contributing
|
2 |
-
============
|
3 |
-
|
4 |
-
New contributions to the library are welcome, just a couple of guidelines:
|
5 |
-
|
6 |
-
* Tabs for indentation, not spaces please.
|
7 |
-
* Please ensure you're changing the individual files in /src, not the concatenated output in the Chart.js file in the root of the repo.
|
8 |
-
* Please check that your code will pass jshint code standards, `gulp jshint` will run this for you.
|
9 |
-
* Please keep pull requests concise, and document new functionality in the relevant .md file.
|
10 |
-
* Consider whether your changes are useful for all users, or if creating a Chart.js extension would be more appropriate.
|
11 |
-
* Please avoid committing in the build Chart.js & Chart.min.js file, as it causes conflicts when merging.
|
12 |
-
|
13 |
-
New Chart Types
|
14 |
-
===============
|
15 |
-
|
16 |
-
Chart.js is designed to be modular. See http://www.chartjs.org/docs/#advanced-usage-writing-new-chart-types
|
17 |
-
|
18 |
-
All discussion of new chart types (horizontal bar charts, X-Y scatter plot, etc.) should be done in the Chart.js Google Group at https://groups.google.com/forum/#!forum/chartjs-user-discussion This will get the most exposure for getting people to help define requirements, complete programming and documentation of your vision.
|
19 |
-
|
20 |
-
Please do not request new chart types in the project issues. Fully implemented, documented, and useful new charts may be maintained in a new repository. Later, we may add a link to selected external repositories from this project.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/Chart.js
DELETED
@@ -1,3379 +0,0 @@
|
|
1 |
-
/*!
|
2 |
-
* Chart.js
|
3 |
-
* http://chartjs.org/
|
4 |
-
* Version: 1.0.1-beta.4
|
5 |
-
*
|
6 |
-
* Copyright 2014 Nick Downie
|
7 |
-
* Released under the MIT license
|
8 |
-
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
|
9 |
-
*/
|
10 |
-
|
11 |
-
|
12 |
-
(function(){
|
13 |
-
|
14 |
-
"use strict";
|
15 |
-
|
16 |
-
//Declare root variable - window in the browser, global on the server
|
17 |
-
var root = this,
|
18 |
-
previous = root.Chart;
|
19 |
-
|
20 |
-
//Occupy the global variable of Chart, and create a simple base class
|
21 |
-
var Chart = function(context){
|
22 |
-
var chart = this;
|
23 |
-
this.canvas = context.canvas;
|
24 |
-
|
25 |
-
this.ctx = context;
|
26 |
-
|
27 |
-
//Variables global to the chart
|
28 |
-
var width = this.width = context.canvas.width;
|
29 |
-
var height = this.height = context.canvas.height;
|
30 |
-
this.aspectRatio = this.width / this.height;
|
31 |
-
//High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
|
32 |
-
helpers.retinaScale(this);
|
33 |
-
|
34 |
-
return this;
|
35 |
-
};
|
36 |
-
//Globally expose the defaults to allow for user updating/changing
|
37 |
-
Chart.defaults = {
|
38 |
-
global: {
|
39 |
-
// Boolean - Whether to animate the chart
|
40 |
-
animation: true,
|
41 |
-
|
42 |
-
// Number - Number of animation steps
|
43 |
-
animationSteps: 60,
|
44 |
-
|
45 |
-
// String - Animation easing effect
|
46 |
-
animationEasing: "easeOutQuart",
|
47 |
-
|
48 |
-
// Boolean - If we should show the scale at all
|
49 |
-
showScale: true,
|
50 |
-
|
51 |
-
// Boolean - If we want to override with a hard coded scale
|
52 |
-
scaleOverride: false,
|
53 |
-
|
54 |
-
// ** Required if scaleOverride is true **
|
55 |
-
// Number - The number of steps in a hard coded scale
|
56 |
-
scaleSteps: null,
|
57 |
-
// Number - The value jump in the hard coded scale
|
58 |
-
scaleStepWidth: null,
|
59 |
-
// Number - The scale starting value
|
60 |
-
scaleStartValue: null,
|
61 |
-
|
62 |
-
// String - Colour of the scale line
|
63 |
-
scaleLineColor: "rgba(0,0,0,.1)",
|
64 |
-
|
65 |
-
// Number - Pixel width of the scale line
|
66 |
-
scaleLineWidth: 1,
|
67 |
-
|
68 |
-
// Boolean - Whether to show labels on the scale
|
69 |
-
scaleShowLabels: true,
|
70 |
-
|
71 |
-
// Interpolated JS string - can access value
|
72 |
-
scaleLabel: "<%=value%>",
|
73 |
-
|
74 |
-
// Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there
|
75 |
-
scaleIntegersOnly: true,
|
76 |
-
|
77 |
-
// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
|
78 |
-
scaleBeginAtZero: false,
|
79 |
-
|
80 |
-
// String - Scale label font declaration for the scale label
|
81 |
-
scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
82 |
-
|
83 |
-
// Number - Scale label font size in pixels
|
84 |
-
scaleFontSize: 12,
|
85 |
-
|
86 |
-
// String - Scale label font weight style
|
87 |
-
scaleFontStyle: "normal",
|
88 |
-
|
89 |
-
// String - Scale label font colour
|
90 |
-
scaleFontColor: "#666",
|
91 |
-
|
92 |
-
// Boolean - whether or not the chart should be responsive and resize when the browser does.
|
93 |
-
responsive: false,
|
94 |
-
|
95 |
-
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
|
96 |
-
maintainAspectRatio: true,
|
97 |
-
|
98 |
-
// Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove
|
99 |
-
showTooltips: true,
|
100 |
-
|
101 |
-
// Array - Array of string names to attach tooltip events
|
102 |
-
tooltipEvents: ["mousemove", "touchstart", "touchmove", "mouseout"],
|
103 |
-
|
104 |
-
// String - Tooltip background colour
|
105 |
-
tooltipFillColor: "rgba(0,0,0,0.8)",
|
106 |
-
|
107 |
-
// String - Tooltip label font declaration for the scale label
|
108 |
-
tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
109 |
-
|
110 |
-
// Number - Tooltip label font size in pixels
|
111 |
-
tooltipFontSize: 14,
|
112 |
-
|
113 |
-
// String - Tooltip font weight style
|
114 |
-
tooltipFontStyle: "normal",
|
115 |
-
|
116 |
-
// String - Tooltip label font colour
|
117 |
-
tooltipFontColor: "#fff",
|
118 |
-
|
119 |
-
// String - Tooltip title font declaration for the scale label
|
120 |
-
tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
121 |
-
|
122 |
-
// Number - Tooltip title font size in pixels
|
123 |
-
tooltipTitleFontSize: 14,
|
124 |
-
|
125 |
-
// String - Tooltip title font weight style
|
126 |
-
tooltipTitleFontStyle: "bold",
|
127 |
-
|
128 |
-
// String - Tooltip title font colour
|
129 |
-
tooltipTitleFontColor: "#fff",
|
130 |
-
|
131 |
-
// Number - pixel width of padding around tooltip text
|
132 |
-
tooltipYPadding: 6,
|
133 |
-
|
134 |
-
// Number - pixel width of padding around tooltip text
|
135 |
-
tooltipXPadding: 6,
|
136 |
-
|
137 |
-
// Number - Size of the caret on the tooltip
|
138 |
-
tooltipCaretSize: 8,
|
139 |
-
|
140 |
-
// Number - Pixel radius of the tooltip border
|
141 |
-
tooltipCornerRadius: 6,
|
142 |
-
|
143 |
-
// Number - Pixel offset from point x to tooltip edge
|
144 |
-
tooltipXOffset: 10,
|
145 |
-
|
146 |
-
// String - Template string for single tooltips
|
147 |
-
tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>",
|
148 |
-
|
149 |
-
// String - Template string for single tooltips
|
150 |
-
multiTooltipTemplate: "<%= value %>",
|
151 |
-
|
152 |
-
// String - Colour behind the legend colour block
|
153 |
-
multiTooltipKeyBackground: '#fff',
|
154 |
-
|
155 |
-
// Function - Will fire on animation progression.
|
156 |
-
onAnimationProgress: function(){},
|
157 |
-
|
158 |
-
// Function - Will fire on animation completion.
|
159 |
-
onAnimationComplete: function(){}
|
160 |
-
|
161 |
-
}
|
162 |
-
};
|
163 |
-
|
164 |
-
//Create a dictionary of chart types, to allow for extension of existing types
|
165 |
-
Chart.types = {};
|
166 |
-
|
167 |
-
//Global Chart helpers object for utility methods and classes
|
168 |
-
var helpers = Chart.helpers = {};
|
169 |
-
|
170 |
-
//-- Basic js utility methods
|
171 |
-
var each = helpers.each = function(loopable,callback,self){
|
172 |
-
var additionalArgs = Array.prototype.slice.call(arguments, 3);
|
173 |
-
// Check to see if null or undefined firstly.
|
174 |
-
if (loopable){
|
175 |
-
if (loopable.length === +loopable.length){
|
176 |
-
var i;
|
177 |
-
for (i=0; i<loopable.length; i++){
|
178 |
-
callback.apply(self,[loopable[i], i].concat(additionalArgs));
|
179 |
-
}
|
180 |
-
}
|
181 |
-
else{
|
182 |
-
for (var item in loopable){
|
183 |
-
callback.apply(self,[loopable[item],item].concat(additionalArgs));
|
184 |
-
}
|
185 |
-
}
|
186 |
-
}
|
187 |
-
},
|
188 |
-
clone = helpers.clone = function(obj){
|
189 |
-
var objClone = {};
|
190 |
-
each(obj,function(value,key){
|
191 |
-
if (obj.hasOwnProperty(key)) objClone[key] = value;
|
192 |
-
});
|
193 |
-
return objClone;
|
194 |
-
},
|
195 |
-
extend = helpers.extend = function(base){
|
196 |
-
each(Array.prototype.slice.call(arguments,1), function(extensionObject) {
|
197 |
-
each(extensionObject,function(value,key){
|
198 |
-
if (extensionObject.hasOwnProperty(key)) base[key] = value;
|
199 |
-
});
|
200 |
-
});
|
201 |
-
return base;
|
202 |
-
},
|
203 |
-
merge = helpers.merge = function(base,master){
|
204 |
-
//Merge properties in left object over to a shallow clone of object right.
|
205 |
-
var args = Array.prototype.slice.call(arguments,0);
|
206 |
-
args.unshift({});
|
207 |
-
return extend.apply(null, args);
|
208 |
-
},
|
209 |
-
indexOf = helpers.indexOf = function(arrayToSearch, item){
|
210 |
-
if (Array.prototype.indexOf) {
|
211 |
-
return arrayToSearch.indexOf(item);
|
212 |
-
}
|
213 |
-
else{
|
214 |
-
for (var i = 0; i < arrayToSearch.length; i++) {
|
215 |
-
if (arrayToSearch[i] === item) return i;
|
216 |
-
}
|
217 |
-
return -1;
|
218 |
-
}
|
219 |
-
},
|
220 |
-
where = helpers.where = function(collection, filterCallback){
|
221 |
-
var filtered = [];
|
222 |
-
|
223 |
-
helpers.each(collection, function(item){
|
224 |
-
if (filterCallback(item)){
|
225 |
-
filtered.push(item);
|
226 |
-
}
|
227 |
-
});
|
228 |
-
|
229 |
-
return filtered;
|
230 |
-
},
|
231 |
-
findNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex){
|
232 |
-
// Default to start of the array
|
233 |
-
if (!startIndex){
|
234 |
-
startIndex = -1;
|
235 |
-
}
|
236 |
-
for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
|
237 |
-
var currentItem = arrayToSearch[i];
|
238 |
-
if (filterCallback(currentItem)){
|
239 |
-
return currentItem;
|
240 |
-
}
|
241 |
-
};
|
242 |
-
},
|
243 |
-
findPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex){
|
244 |
-
// Default to end of the array
|
245 |
-
if (!startIndex){
|
246 |
-
startIndex = arrayToSearch.length;
|
247 |
-
}
|
248 |
-
for (var i = startIndex - 1; i >= 0; i--) {
|
249 |
-
var currentItem = arrayToSearch[i];
|
250 |
-
if (filterCallback(currentItem)){
|
251 |
-
return currentItem;
|
252 |
-
}
|
253 |
-
};
|
254 |
-
},
|
255 |
-
inherits = helpers.inherits = function(extensions){
|
256 |
-
//Basic javascript inheritance based on the model created in Backbone.js
|
257 |
-
var parent = this;
|
258 |
-
var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function(){ return parent.apply(this, arguments); };
|
259 |
-
|
260 |
-
var Surrogate = function(){ this.constructor = ChartElement;};
|
261 |
-
Surrogate.prototype = parent.prototype;
|
262 |
-
ChartElement.prototype = new Surrogate();
|
263 |
-
|
264 |
-
ChartElement.extend = inherits;
|
265 |
-
|
266 |
-
if (extensions) extend(ChartElement.prototype, extensions);
|
267 |
-
|
268 |
-
ChartElement.__super__ = parent.prototype;
|
269 |
-
|
270 |
-
return ChartElement;
|
271 |
-
},
|
272 |
-
noop = helpers.noop = function(){},
|
273 |
-
uid = helpers.uid = (function(){
|
274 |
-
var id=0;
|
275 |
-
return function(){
|
276 |
-
return "chart-" + id++;
|
277 |
-
};
|
278 |
-
})(),
|
279 |
-
warn = helpers.warn = function(str){
|
280 |
-
//Method for warning of errors
|
281 |
-
if (window.console && typeof window.console.warn == "function") console.warn(str);
|
282 |
-
},
|
283 |
-
amd = helpers.amd = (typeof define == 'function' && define.amd),
|
284 |
-
//-- Math methods
|
285 |
-
isNumber = helpers.isNumber = function(n){
|
286 |
-
return !isNaN(parseFloat(n)) && isFinite(n);
|
287 |
-
},
|
288 |
-
max = helpers.max = function(array){
|
289 |
-
return Math.max.apply( Math, array );
|
290 |
-
},
|
291 |
-
min = helpers.min = function(array){
|
292 |
-
return Math.min.apply( Math, array );
|
293 |
-
},
|
294 |
-
cap = helpers.cap = function(valueToCap,maxValue,minValue){
|
295 |
-
if(isNumber(maxValue)) {
|
296 |
-
if( valueToCap > maxValue ) {
|
297 |
-
return maxValue;
|
298 |
-
}
|
299 |
-
}
|
300 |
-
else if(isNumber(minValue)){
|
301 |
-
if ( valueToCap < minValue ){
|
302 |
-
return minValue;
|
303 |
-
}
|
304 |
-
}
|
305 |
-
return valueToCap;
|
306 |
-
},
|
307 |
-
getDecimalPlaces = helpers.getDecimalPlaces = function(num){
|
308 |
-
if (num%1!==0 && isNumber(num)){
|
309 |
-
return num.toString().split(".")[1].length;
|
310 |
-
}
|
311 |
-
else {
|
312 |
-
return 0;
|
313 |
-
}
|
314 |
-
},
|
315 |
-
toRadians = helpers.radians = function(degrees){
|
316 |
-
return degrees * (Math.PI/180);
|
317 |
-
},
|
318 |
-
// Gets the angle from vertical upright to the point about a centre.
|
319 |
-
getAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){
|
320 |
-
var distanceFromXCenter = anglePoint.x - centrePoint.x,
|
321 |
-
distanceFromYCenter = anglePoint.y - centrePoint.y,
|
322 |
-
radialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
|
323 |
-
|
324 |
-
|
325 |
-
var angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);
|
326 |
-
|
327 |
-
//If the segment is in the top left quadrant, we need to add another rotation to the angle
|
328 |
-
if (distanceFromXCenter < 0 && distanceFromYCenter < 0){
|
329 |
-
angle += Math.PI*2;
|
330 |
-
}
|
331 |
-
|
332 |
-
return {
|
333 |
-
angle: angle,
|
334 |
-
distance: radialDistanceFromCenter
|
335 |
-
};
|
336 |
-
},
|
337 |
-
aliasPixel = helpers.aliasPixel = function(pixelWidth){
|
338 |
-
return (pixelWidth % 2 === 0) ? 0 : 0.5;
|
339 |
-
},
|
340 |
-
splineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){
|
341 |
-
//Props to Rob Spencer at scaled innovation for his post on splining between points
|
342 |
-
//http://scaledinnovation.com/analytics/splines/aboutSplines.html
|
343 |
-
var d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),
|
344 |
-
d12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),
|
345 |
-
fa=t*d01/(d01+d12),// scaling factor for triangle Ta
|
346 |
-
fb=t*d12/(d01+d12);
|
347 |
-
return {
|
348 |
-
inner : {
|
349 |
-
x : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),
|
350 |
-
y : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)
|
351 |
-
},
|
352 |
-
outer : {
|
353 |
-
x: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),
|
354 |
-
y : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)
|
355 |
-
}
|
356 |
-
};
|
357 |
-
},
|
358 |
-
calculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){
|
359 |
-
return Math.floor(Math.log(val) / Math.LN10);
|
360 |
-
},
|
361 |
-
calculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){
|
362 |
-
|
363 |
-
//Set a minimum step of two - a point at the top of the graph, and a point at the base
|
364 |
-
var minSteps = 2,
|
365 |
-
maxSteps = Math.floor(drawingSize/(textSize * 1.5)),
|
366 |
-
skipFitting = (minSteps >= maxSteps);
|
367 |
-
|
368 |
-
var maxValue = max(valuesArray),
|
369 |
-
minValue = min(valuesArray);
|
370 |
-
|
371 |
-
// We need some degree of seperation here to calculate the scales if all the values are the same
|
372 |
-
// Adding/minusing 0.5 will give us a range of 1.
|
373 |
-
if (maxValue === minValue){
|
374 |
-
maxValue += 0.5;
|
375 |
-
// So we don't end up with a graph with a negative start value if we've said always start from zero
|
376 |
-
if (minValue >= 0.5 && !startFromZero){
|
377 |
-
minValue -= 0.5;
|
378 |
-
}
|
379 |
-
else{
|
380 |
-
// Make up a whole number above the values
|
381 |
-
maxValue += 0.5;
|
382 |
-
}
|
383 |
-
}
|
384 |
-
|
385 |
-
var valueRange = Math.abs(maxValue - minValue),
|
386 |
-
rangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),
|
387 |
-
graphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
|
388 |
-
graphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
|
389 |
-
graphRange = graphMax - graphMin,
|
390 |
-
stepValue = Math.pow(10, rangeOrderOfMagnitude),
|
391 |
-
numberOfSteps = Math.round(graphRange / stepValue);
|
392 |
-
|
393 |
-
//If we have more space on the graph we'll use it to give more definition to the data
|
394 |
-
while((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {
|
395 |
-
if(numberOfSteps > maxSteps){
|
396 |
-
stepValue *=2;
|
397 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
398 |
-
// Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.
|
399 |
-
if (numberOfSteps % 1 !== 0){
|
400 |
-
skipFitting = true;
|
401 |
-
}
|
402 |
-
}
|
403 |
-
//We can fit in double the amount of scale points on the scale
|
404 |
-
else{
|
405 |
-
//If user has declared ints only, and the step value isn't a decimal
|
406 |
-
if (integersOnly && rangeOrderOfMagnitude >= 0){
|
407 |
-
//If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float
|
408 |
-
if(stepValue/2 % 1 === 0){
|
409 |
-
stepValue /=2;
|
410 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
411 |
-
}
|
412 |
-
//If it would make it a float break out of the loop
|
413 |
-
else{
|
414 |
-
break;
|
415 |
-
}
|
416 |
-
}
|
417 |
-
//If the scale doesn't have to be an int, make the scale more granular anyway.
|
418 |
-
else{
|
419 |
-
stepValue /=2;
|
420 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
421 |
-
}
|
422 |
-
|
423 |
-
}
|
424 |
-
}
|
425 |
-
|
426 |
-
if (skipFitting){
|
427 |
-
numberOfSteps = minSteps;
|
428 |
-
stepValue = graphRange / numberOfSteps;
|
429 |
-
}
|
430 |
-
|
431 |
-
return {
|
432 |
-
steps : numberOfSteps,
|
433 |
-
stepValue : stepValue,
|
434 |
-
min : graphMin,
|
435 |
-
max : graphMin + (numberOfSteps * stepValue)
|
436 |
-
};
|
437 |
-
|
438 |
-
},
|
439 |
-
/* jshint ignore:start */
|
440 |
-
// Blows up jshint errors based on the new Function constructor
|
441 |
-
//Templating methods
|
442 |
-
//Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/
|
443 |
-
template = helpers.template = function(templateString, valuesObject){
|
444 |
-
// If templateString is function rather than string-template - call the function for valuesObject
|
445 |
-
if(templateString instanceof Function){
|
446 |
-
return templateString(valuesObject);
|
447 |
-
}
|
448 |
-
|
449 |
-
var cache = {};
|
450 |
-
function tmpl(str, data){
|
451 |
-
// Figure out if we're getting a template, or if we need to
|
452 |
-
// load the template - and be sure to cache the result.
|
453 |
-
var fn = !/\W/.test(str) ?
|
454 |
-
cache[str] = cache[str] :
|
455 |
-
|
456 |
-
// Generate a reusable function that will serve as a template
|
457 |
-
// generator (and which will be cached).
|
458 |
-
new Function("obj",
|
459 |
-
"var p=[],print=function(){p.push.apply(p,arguments);};" +
|
460 |
-
|
461 |
-
// Introduce the data as local variables using with(){}
|
462 |
-
"with(obj){p.push('" +
|
463 |
-
|
464 |
-
// Convert the template into pure JavaScript
|
465 |
-
str
|
466 |
-
.replace(/[\r\t\n]/g, " ")
|
467 |
-
.split("<%").join("\t")
|
468 |
-
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
|
469 |
-
.replace(/\t=(.*?)%>/g, "',$1,'")
|
470 |
-
.split("\t").join("');")
|
471 |
-
.split("%>").join("p.push('")
|
472 |
-
.split("\r").join("\\'") +
|
473 |
-
"');}return p.join('');"
|
474 |
-
);
|
475 |
-
|
476 |
-
// Provide some basic currying to the user
|
477 |
-
return data ? fn( data ) : fn;
|
478 |
-
}
|
479 |
-
return tmpl(templateString,valuesObject);
|
480 |
-
},
|
481 |
-
/* jshint ignore:end */
|
482 |
-
generateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){
|
483 |
-
var labelsArray = new Array(numberOfSteps);
|
484 |
-
if (labelTemplateString){
|
485 |
-
each(labelsArray,function(val,index){
|
486 |
-
labelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});
|
487 |
-
});
|
488 |
-
}
|
489 |
-
return labelsArray;
|
490 |
-
},
|
491 |
-
//--Animation methods
|
492 |
-
//Easing functions adapted from Robert Penner's easing equations
|
493 |
-
//http://www.robertpenner.com/easing/
|
494 |
-
easingEffects = helpers.easingEffects = {
|
495 |
-
linear: function (t) {
|
496 |
-
return t;
|
497 |
-
},
|
498 |
-
easeInQuad: function (t) {
|
499 |
-
return t * t;
|
500 |
-
},
|
501 |
-
easeOutQuad: function (t) {
|
502 |
-
return -1 * t * (t - 2);
|
503 |
-
},
|
504 |
-
easeInOutQuad: function (t) {
|
505 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * t * t;
|
506 |
-
return -1 / 2 * ((--t) * (t - 2) - 1);
|
507 |
-
},
|
508 |
-
easeInCubic: function (t) {
|
509 |
-
return t * t * t;
|
510 |
-
},
|
511 |
-
easeOutCubic: function (t) {
|
512 |
-
return 1 * ((t = t / 1 - 1) * t * t + 1);
|
513 |
-
},
|
514 |
-
easeInOutCubic: function (t) {
|
515 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t;
|
516 |
-
return 1 / 2 * ((t -= 2) * t * t + 2);
|
517 |
-
},
|
518 |
-
easeInQuart: function (t) {
|
519 |
-
return t * t * t * t;
|
520 |
-
},
|
521 |
-
easeOutQuart: function (t) {
|
522 |
-
return -1 * ((t = t / 1 - 1) * t * t * t - 1);
|
523 |
-
},
|
524 |
-
easeInOutQuart: function (t) {
|
525 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t;
|
526 |
-
return -1 / 2 * ((t -= 2) * t * t * t - 2);
|
527 |
-
},
|
528 |
-
easeInQuint: function (t) {
|
529 |
-
return 1 * (t /= 1) * t * t * t * t;
|
530 |
-
},
|
531 |
-
easeOutQuint: function (t) {
|
532 |
-
return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);
|
533 |
-
},
|
534 |
-
easeInOutQuint: function (t) {
|
535 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t * t;
|
536 |
-
return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
|
537 |
-
},
|
538 |
-
easeInSine: function (t) {
|
539 |
-
return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
|
540 |
-
},
|
541 |
-
easeOutSine: function (t) {
|
542 |
-
return 1 * Math.sin(t / 1 * (Math.PI / 2));
|
543 |
-
},
|
544 |
-
easeInOutSine: function (t) {
|
545 |
-
return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
|
546 |
-
},
|
547 |
-
easeInExpo: function (t) {
|
548 |
-
return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
|
549 |
-
},
|
550 |
-
easeOutExpo: function (t) {
|
551 |
-
return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
|
552 |
-
},
|
553 |
-
easeInOutExpo: function (t) {
|
554 |
-
if (t === 0) return 0;
|
555 |
-
if (t === 1) return 1;
|
556 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * Math.pow(2, 10 * (t - 1));
|
557 |
-
return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
|
558 |
-
},
|
559 |
-
easeInCirc: function (t) {
|
560 |
-
if (t >= 1) return t;
|
561 |
-
return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
|
562 |
-
},
|
563 |
-
easeOutCirc: function (t) {
|
564 |
-
return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
|
565 |
-
},
|
566 |
-
easeInOutCirc: function (t) {
|
567 |
-
if ((t /= 1 / 2) < 1) return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
|
568 |
-
return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
|
569 |
-
},
|
570 |
-
easeInElastic: function (t) {
|
571 |
-
var s = 1.70158;
|
572 |
-
var p = 0;
|
573 |
-
var a = 1;
|
574 |
-
if (t === 0) return 0;
|
575 |
-
if ((t /= 1) == 1) return 1;
|
576 |
-
if (!p) p = 1 * 0.3;
|
577 |
-
if (a < Math.abs(1)) {
|
578 |
-
a = 1;
|
579 |
-
s = p / 4;
|
580 |
-
} else s = p / (2 * Math.PI) * Math.asin(1 / a);
|
581 |
-
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
582 |
-
},
|
583 |
-
easeOutElastic: function (t) {
|
584 |
-
var s = 1.70158;
|
585 |
-
var p = 0;
|
586 |
-
var a = 1;
|
587 |
-
if (t === 0) return 0;
|
588 |
-
if ((t /= 1) == 1) return 1;
|
589 |
-
if (!p) p = 1 * 0.3;
|
590 |
-
if (a < Math.abs(1)) {
|
591 |
-
a = 1;
|
592 |
-
s = p / 4;
|
593 |
-
} else s = p / (2 * Math.PI) * Math.asin(1 / a);
|
594 |
-
return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
|
595 |
-
},
|
596 |
-
easeInOutElastic: function (t) {
|
597 |
-
var s = 1.70158;
|
598 |
-
var p = 0;
|
599 |
-
var a = 1;
|
600 |
-
if (t === 0) return 0;
|
601 |
-
if ((t /= 1 / 2) == 2) return 1;
|
602 |
-
if (!p) p = 1 * (0.3 * 1.5);
|
603 |
-
if (a < Math.abs(1)) {
|
604 |
-
a = 1;
|
605 |
-
s = p / 4;
|
606 |
-
} else s = p / (2 * Math.PI) * Math.asin(1 / a);
|
607 |
-
if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
608 |
-
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
|
609 |
-
},
|
610 |
-
easeInBack: function (t) {
|
611 |
-
var s = 1.70158;
|
612 |
-
return 1 * (t /= 1) * t * ((s + 1) * t - s);
|
613 |
-
},
|
614 |
-
easeOutBack: function (t) {
|
615 |
-
var s = 1.70158;
|
616 |
-
return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
|
617 |
-
},
|
618 |
-
easeInOutBack: function (t) {
|
619 |
-
var s = 1.70158;
|
620 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
|
621 |
-
return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
|
622 |
-
},
|
623 |
-
easeInBounce: function (t) {
|
624 |
-
return 1 - easingEffects.easeOutBounce(1 - t);
|
625 |
-
},
|
626 |
-
easeOutBounce: function (t) {
|
627 |
-
if ((t /= 1) < (1 / 2.75)) {
|
628 |
-
return 1 * (7.5625 * t * t);
|
629 |
-
} else if (t < (2 / 2.75)) {
|
630 |
-
return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
|
631 |
-
} else if (t < (2.5 / 2.75)) {
|
632 |
-
return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
|
633 |
-
} else {
|
634 |
-
return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
|
635 |
-
}
|
636 |
-
},
|
637 |
-
easeInOutBounce: function (t) {
|
638 |
-
if (t < 1 / 2) return easingEffects.easeInBounce(t * 2) * 0.5;
|
639 |
-
return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
|
640 |
-
}
|
641 |
-
},
|
642 |
-
//Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
|
643 |
-
requestAnimFrame = helpers.requestAnimFrame = (function(){
|
644 |
-
return window.requestAnimationFrame ||
|
645 |
-
window.webkitRequestAnimationFrame ||
|
646 |
-
window.mozRequestAnimationFrame ||
|
647 |
-
window.oRequestAnimationFrame ||
|
648 |
-
window.msRequestAnimationFrame ||
|
649 |
-
function(callback) {
|
650 |
-
return window.setTimeout(callback, 1000 / 60);
|
651 |
-
};
|
652 |
-
})(),
|
653 |
-
cancelAnimFrame = helpers.cancelAnimFrame = (function(){
|
654 |
-
return window.cancelAnimationFrame ||
|
655 |
-
window.webkitCancelAnimationFrame ||
|
656 |
-
window.mozCancelAnimationFrame ||
|
657 |
-
window.oCancelAnimationFrame ||
|
658 |
-
window.msCancelAnimationFrame ||
|
659 |
-
function(callback) {
|
660 |
-
return window.clearTimeout(callback, 1000 / 60);
|
661 |
-
};
|
662 |
-
})(),
|
663 |
-
animationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){
|
664 |
-
|
665 |
-
var currentStep = 0,
|
666 |
-
easingFunction = easingEffects[easingString] || easingEffects.linear;
|
667 |
-
|
668 |
-
var animationFrame = function(){
|
669 |
-
currentStep++;
|
670 |
-
var stepDecimal = currentStep/totalSteps;
|
671 |
-
var easeDecimal = easingFunction(stepDecimal);
|
672 |
-
|
673 |
-
callback.call(chartInstance,easeDecimal,stepDecimal, currentStep);
|
674 |
-
onProgress.call(chartInstance,easeDecimal,stepDecimal);
|
675 |
-
if (currentStep < totalSteps){
|
676 |
-
chartInstance.animationFrame = requestAnimFrame(animationFrame);
|
677 |
-
} else{
|
678 |
-
onComplete.apply(chartInstance);
|
679 |
-
}
|
680 |
-
};
|
681 |
-
requestAnimFrame(animationFrame);
|
682 |
-
},
|
683 |
-
//-- DOM methods
|
684 |
-
getRelativePosition = helpers.getRelativePosition = function(evt){
|
685 |
-
var mouseX, mouseY;
|
686 |
-
var e = evt.originalEvent || evt,
|
687 |
-
canvas = evt.currentTarget || evt.srcElement,
|
688 |
-
boundingRect = canvas.getBoundingClientRect();
|
689 |
-
|
690 |
-
if (e.touches){
|
691 |
-
mouseX = e.touches[0].clientX - boundingRect.left;
|
692 |
-
mouseY = e.touches[0].clientY - boundingRect.top;
|
693 |
-
|
694 |
-
}
|
695 |
-
else{
|
696 |
-
mouseX = e.clientX - boundingRect.left;
|
697 |
-
mouseY = e.clientY - boundingRect.top;
|
698 |
-
}
|
699 |
-
|
700 |
-
return {
|
701 |
-
x : mouseX,
|
702 |
-
y : mouseY
|
703 |
-
};
|
704 |
-
|
705 |
-
},
|
706 |
-
addEvent = helpers.addEvent = function(node,eventType,method){
|
707 |
-
if (node.addEventListener){
|
708 |
-
node.addEventListener(eventType,method);
|
709 |
-
} else if (node.attachEvent){
|
710 |
-
node.attachEvent("on"+eventType, method);
|
711 |
-
} else {
|
712 |
-
node["on"+eventType] = method;
|
713 |
-
}
|
714 |
-
},
|
715 |
-
removeEvent = helpers.removeEvent = function(node, eventType, handler){
|
716 |
-
if (node.removeEventListener){
|
717 |
-
node.removeEventListener(eventType, handler, false);
|
718 |
-
} else if (node.detachEvent){
|
719 |
-
node.detachEvent("on"+eventType,handler);
|
720 |
-
} else{
|
721 |
-
node["on" + eventType] = noop;
|
722 |
-
}
|
723 |
-
},
|
724 |
-
bindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){
|
725 |
-
// Create the events object if it's not already present
|
726 |
-
if (!chartInstance.events) chartInstance.events = {};
|
727 |
-
|
728 |
-
each(arrayOfEvents,function(eventName){
|
729 |
-
chartInstance.events[eventName] = function(){
|
730 |
-
handler.apply(chartInstance, arguments);
|
731 |
-
};
|
732 |
-
addEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);
|
733 |
-
});
|
734 |
-
},
|
735 |
-
unbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) {
|
736 |
-
each(arrayOfEvents, function(handler,eventName){
|
737 |
-
removeEvent(chartInstance.chart.canvas, eventName, handler);
|
738 |
-
});
|
739 |
-
},
|
740 |
-
getMaximumWidth = helpers.getMaximumWidth = function(domNode){
|
741 |
-
var container = domNode.parentNode;
|
742 |
-
// TODO = check cross browser stuff with this.
|
743 |
-
return container.clientWidth;
|
744 |
-
},
|
745 |
-
getMaximumHeight = helpers.getMaximumHeight = function(domNode){
|
746 |
-
var container = domNode.parentNode;
|
747 |
-
// TODO = check cross browser stuff with this.
|
748 |
-
return container.clientHeight;
|
749 |
-
},
|
750 |
-
getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support
|
751 |
-
retinaScale = helpers.retinaScale = function(chart){
|
752 |
-
var ctx = chart.ctx,
|
753 |
-
width = chart.canvas.width,
|
754 |
-
height = chart.canvas.height;
|
755 |
-
|
756 |
-
if (window.devicePixelRatio) {
|
757 |
-
ctx.canvas.style.width = width + "px";
|
758 |
-
ctx.canvas.style.height = height + "px";
|
759 |
-
ctx.canvas.height = height * window.devicePixelRatio;
|
760 |
-
ctx.canvas.width = width * window.devicePixelRatio;
|
761 |
-
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
|
762 |
-
}
|
763 |
-
},
|
764 |
-
//-- Canvas methods
|
765 |
-
clear = helpers.clear = function(chart){
|
766 |
-
chart.ctx.clearRect(0,0,chart.width,chart.height);
|
767 |
-
},
|
768 |
-
fontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){
|
769 |
-
return fontStyle + " " + pixelSize+"px " + fontFamily;
|
770 |
-
},
|
771 |
-
longestText = helpers.longestText = function(ctx,font,arrayOfStrings){
|
772 |
-
ctx.font = font;
|
773 |
-
var longest = 0;
|
774 |
-
each(arrayOfStrings,function(string){
|
775 |
-
var textWidth = ctx.measureText(string).width;
|
776 |
-
longest = (textWidth > longest) ? textWidth : longest;
|
777 |
-
});
|
778 |
-
return longest;
|
779 |
-
},
|
780 |
-
drawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){
|
781 |
-
ctx.beginPath();
|
782 |
-
ctx.moveTo(x + radius, y);
|
783 |
-
ctx.lineTo(x + width - radius, y);
|
784 |
-
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
785 |
-
ctx.lineTo(x + width, y + height - radius);
|
786 |
-
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
|
787 |
-
ctx.lineTo(x + radius, y + height);
|
788 |
-
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
789 |
-
ctx.lineTo(x, y + radius);
|
790 |
-
ctx.quadraticCurveTo(x, y, x + radius, y);
|
791 |
-
ctx.closePath();
|
792 |
-
};
|
793 |
-
|
794 |
-
|
795 |
-
//Store a reference to each instance - allowing us to globally resize chart instances on window resize.
|
796 |
-
//Destroy method on the chart will remove the instance of the chart from this reference.
|
797 |
-
Chart.instances = {};
|
798 |
-
|
799 |
-
Chart.Type = function(data,options,chart){
|
800 |
-
this.options = options;
|
801 |
-
this.chart = chart;
|
802 |
-
this.id = uid();
|
803 |
-
//Add the chart instance to the global namespace
|
804 |
-
Chart.instances[this.id] = this;
|
805 |
-
|
806 |
-
// Initialize is always called when a chart type is created
|
807 |
-
// By default it is a no op, but it should be extended
|
808 |
-
if (options.responsive){
|
809 |
-
this.resize();
|
810 |
-
}
|
811 |
-
this.initialize.call(this,data);
|
812 |
-
};
|
813 |
-
|
814 |
-
//Core methods that'll be a part of every chart type
|
815 |
-
extend(Chart.Type.prototype,{
|
816 |
-
initialize : function(){return this;},
|
817 |
-
clear : function(){
|
818 |
-
clear(this.chart);
|
819 |
-
return this;
|
820 |
-
},
|
821 |
-
stop : function(){
|
822 |
-
// Stops any current animation loop occuring
|
823 |
-
helpers.cancelAnimFrame.call(root, this.animationFrame);
|
824 |
-
return this;
|
825 |
-
},
|
826 |
-
resize : function(callback){
|
827 |
-
this.stop();
|
828 |
-
var canvas = this.chart.canvas,
|
829 |
-
newWidth = getMaximumWidth(this.chart.canvas),
|
830 |
-
newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);
|
831 |
-
|
832 |
-
canvas.width = this.chart.width = newWidth;
|
833 |
-
canvas.height = this.chart.height = newHeight;
|
834 |
-
|
835 |
-
retinaScale(this.chart);
|
836 |
-
|
837 |
-
if (typeof callback === "function"){
|
838 |
-
callback.apply(this, Array.prototype.slice.call(arguments, 1));
|
839 |
-
}
|
840 |
-
return this;
|
841 |
-
},
|
842 |
-
reflow : noop,
|
843 |
-
render : function(reflow){
|
844 |
-
if (reflow){
|
845 |
-
this.reflow();
|
846 |
-
}
|
847 |
-
if (this.options.animation && !reflow){
|
848 |
-
helpers.animationLoop(
|
849 |
-
this.draw,
|
850 |
-
this.options.animationSteps,
|
851 |
-
this.options.animationEasing,
|
852 |
-
this.options.onAnimationProgress,
|
853 |
-
this.options.onAnimationComplete,
|
854 |
-
this
|
855 |
-
);
|
856 |
-
}
|
857 |
-
else{
|
858 |
-
this.draw();
|
859 |
-
this.options.onAnimationComplete.call(this);
|
860 |
-
}
|
861 |
-
return this;
|
862 |
-
},
|
863 |
-
generateLegend : function(){
|
864 |
-
return template(this.options.legendTemplate,this);
|
865 |
-
},
|
866 |
-
destroy : function(){
|
867 |
-
this.clear();
|
868 |
-
unbindEvents(this, this.events);
|
869 |
-
delete Chart.instances[this.id];
|
870 |
-
},
|
871 |
-
showTooltip : function(ChartElements, forceRedraw){
|
872 |
-
// Only redraw the chart if we've actually changed what we're hovering on.
|
873 |
-
if (typeof this.activeElements === 'undefined') this.activeElements = [];
|
874 |
-
|
875 |
-
var isChanged = (function(Elements){
|
876 |
-
var changed = false;
|
877 |
-
|
878 |
-
if (Elements.length !== this.activeElements.length){
|
879 |
-
changed = true;
|
880 |
-
return changed;
|
881 |
-
}
|
882 |
-
|
883 |
-
each(Elements, function(element, index){
|
884 |
-
if (element !== this.activeElements[index]){
|
885 |
-
changed = true;
|
886 |
-
}
|
887 |
-
}, this);
|
888 |
-
return changed;
|
889 |
-
}).call(this, ChartElements);
|
890 |
-
|
891 |
-
if (!isChanged && !forceRedraw){
|
892 |
-
return;
|
893 |
-
}
|
894 |
-
else{
|
895 |
-
this.activeElements = ChartElements;
|
896 |
-
}
|
897 |
-
this.draw();
|
898 |
-
if (ChartElements.length > 0){
|
899 |
-
// If we have multiple datasets, show a MultiTooltip for all of the data points at that index
|
900 |
-
if (this.datasets && this.datasets.length > 1) {
|
901 |
-
var dataArray,
|
902 |
-
dataIndex;
|
903 |
-
|
904 |
-
for (var i = this.datasets.length - 1; i >= 0; i--) {
|
905 |
-
dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
|
906 |
-
dataIndex = indexOf(dataArray, ChartElements[0]);
|
907 |
-
if (dataIndex !== -1){
|
908 |
-
break;
|
909 |
-
}
|
910 |
-
}
|
911 |
-
var tooltipLabels = [],
|
912 |
-
tooltipColors = [],
|
913 |
-
medianPosition = (function(index) {
|
914 |
-
|
915 |
-
// Get all the points at that particular index
|
916 |
-
var Elements = [],
|
917 |
-
dataCollection,
|
918 |
-
xPositions = [],
|
919 |
-
yPositions = [],
|
920 |
-
xMax,
|
921 |
-
yMax,
|
922 |
-
xMin,
|
923 |
-
yMin;
|
924 |
-
helpers.each(this.datasets, function(dataset){
|
925 |
-
dataCollection = dataset.points || dataset.bars || dataset.segments;
|
926 |
-
if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){
|
927 |
-
Elements.push(dataCollection[dataIndex]);
|
928 |
-
}
|
929 |
-
});
|
930 |
-
|
931 |
-
helpers.each(Elements, function(element) {
|
932 |
-
xPositions.push(element.x);
|
933 |
-
yPositions.push(element.y);
|
934 |
-
|
935 |
-
|
936 |
-
//Include any colour information about the element
|
937 |
-
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
|
938 |
-
tooltipColors.push({
|
939 |
-
fill: element._saved.fillColor || element.fillColor,
|
940 |
-
stroke: element._saved.strokeColor || element.strokeColor
|
941 |
-
});
|
942 |
-
|
943 |
-
}, this);
|
944 |
-
|
945 |
-
yMin = min(yPositions);
|
946 |
-
yMax = max(yPositions);
|
947 |
-
|
948 |
-
xMin = min(xPositions);
|
949 |
-
xMax = max(xPositions);
|
950 |
-
|
951 |
-
return {
|
952 |
-
x: (xMin > this.chart.width/2) ? xMin : xMax,
|
953 |
-
y: (yMin + yMax)/2
|
954 |
-
};
|
955 |
-
}).call(this, dataIndex);
|
956 |
-
|
957 |
-
new Chart.MultiTooltip({
|
958 |
-
x: medianPosition.x,
|
959 |
-
y: medianPosition.y,
|
960 |
-
xPadding: this.options.tooltipXPadding,
|
961 |
-
yPadding: this.options.tooltipYPadding,
|
962 |
-
xOffset: this.options.tooltipXOffset,
|
963 |
-
fillColor: this.options.tooltipFillColor,
|
964 |
-
textColor: this.options.tooltipFontColor,
|
965 |
-
fontFamily: this.options.tooltipFontFamily,
|
966 |
-
fontStyle: this.options.tooltipFontStyle,
|
967 |
-
fontSize: this.options.tooltipFontSize,
|
968 |
-
titleTextColor: this.options.tooltipTitleFontColor,
|
969 |
-
titleFontFamily: this.options.tooltipTitleFontFamily,
|
970 |
-
titleFontStyle: this.options.tooltipTitleFontStyle,
|
971 |
-
titleFontSize: this.options.tooltipTitleFontSize,
|
972 |
-
cornerRadius: this.options.tooltipCornerRadius,
|
973 |
-
labels: tooltipLabels,
|
974 |
-
legendColors: tooltipColors,
|
975 |
-
legendColorBackground : this.options.multiTooltipKeyBackground,
|
976 |
-
title: ChartElements[0].label,
|
977 |
-
chart: this.chart,
|
978 |
-
ctx: this.chart.ctx
|
979 |
-
}).draw();
|
980 |
-
|
981 |
-
} else {
|
982 |
-
each(ChartElements, function(Element) {
|
983 |
-
var tooltipPosition = Element.tooltipPosition();
|
984 |
-
new Chart.Tooltip({
|
985 |
-
x: Math.round(tooltipPosition.x),
|
986 |
-
y: Math.round(tooltipPosition.y),
|
987 |
-
xPadding: this.options.tooltipXPadding,
|
988 |
-
yPadding: this.options.tooltipYPadding,
|
989 |
-
fillColor: this.options.tooltipFillColor,
|
990 |
-
textColor: this.options.tooltipFontColor,
|
991 |
-
fontFamily: this.options.tooltipFontFamily,
|
992 |
-
fontStyle: this.options.tooltipFontStyle,
|
993 |
-
fontSize: this.options.tooltipFontSize,
|
994 |
-
caretHeight: this.options.tooltipCaretSize,
|
995 |
-
cornerRadius: this.options.tooltipCornerRadius,
|
996 |
-
text: template(this.options.tooltipTemplate, Element),
|
997 |
-
chart: this.chart
|
998 |
-
}).draw();
|
999 |
-
}, this);
|
1000 |
-
}
|
1001 |
-
}
|
1002 |
-
return this;
|
1003 |
-
},
|
1004 |
-
toBase64Image : function(){
|
1005 |
-
return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
|
1006 |
-
}
|
1007 |
-
});
|
1008 |
-
|
1009 |
-
Chart.Type.extend = function(extensions){
|
1010 |
-
|
1011 |
-
var parent = this;
|
1012 |
-
|
1013 |
-
var ChartType = function(){
|
1014 |
-
return parent.apply(this,arguments);
|
1015 |
-
};
|
1016 |
-
|
1017 |
-
//Copy the prototype object of the this class
|
1018 |
-
ChartType.prototype = clone(parent.prototype);
|
1019 |
-
//Now overwrite some of the properties in the base class with the new extensions
|
1020 |
-
extend(ChartType.prototype, extensions);
|
1021 |
-
|
1022 |
-
ChartType.extend = Chart.Type.extend;
|
1023 |
-
|
1024 |
-
if (extensions.name || parent.prototype.name){
|
1025 |
-
|
1026 |
-
var chartName = extensions.name || parent.prototype.name;
|
1027 |
-
//Assign any potential default values of the new chart type
|
1028 |
-
|
1029 |
-
//If none are defined, we'll use a clone of the chart type this is being extended from.
|
1030 |
-
//I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart
|
1031 |
-
//doesn't define some defaults of their own.
|
1032 |
-
|
1033 |
-
var baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {};
|
1034 |
-
|
1035 |
-
Chart.defaults[chartName] = extend(baseDefaults,extensions.defaults);
|
1036 |
-
|
1037 |
-
Chart.types[chartName] = ChartType;
|
1038 |
-
|
1039 |
-
//Register this new chart type in the Chart prototype
|
1040 |
-
Chart.prototype[chartName] = function(data,options){
|
1041 |
-
var config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {});
|
1042 |
-
return new ChartType(data,config,this);
|
1043 |
-
};
|
1044 |
-
} else{
|
1045 |
-
warn("Name not provided for this chart, so it hasn't been registered");
|
1046 |
-
}
|
1047 |
-
return parent;
|
1048 |
-
};
|
1049 |
-
|
1050 |
-
Chart.Element = function(configuration){
|
1051 |
-
extend(this,configuration);
|
1052 |
-
this.initialize.apply(this,arguments);
|
1053 |
-
this.save();
|
1054 |
-
};
|
1055 |
-
extend(Chart.Element.prototype,{
|
1056 |
-
initialize : function(){},
|
1057 |
-
restore : function(props){
|
1058 |
-
if (!props){
|
1059 |
-
extend(this,this._saved);
|
1060 |
-
} else {
|
1061 |
-
each(props,function(key){
|
1062 |
-
this[key] = this._saved[key];
|
1063 |
-
},this);
|
1064 |
-
}
|
1065 |
-
return this;
|
1066 |
-
},
|
1067 |
-
save : function(){
|
1068 |
-
this._saved = clone(this);
|
1069 |
-
delete this._saved._saved;
|
1070 |
-
return this;
|
1071 |
-
},
|
1072 |
-
update : function(newProps){
|
1073 |
-
each(newProps,function(value,key){
|
1074 |
-
this._saved[key] = this[key];
|
1075 |
-
this[key] = value;
|
1076 |
-
},this);
|
1077 |
-
return this;
|
1078 |
-
},
|
1079 |
-
transition : function(props,ease){
|
1080 |
-
each(props,function(value,key){
|
1081 |
-
this[key] = ((value - this._saved[key]) * ease) + this._saved[key];
|
1082 |
-
},this);
|
1083 |
-
return this;
|
1084 |
-
},
|
1085 |
-
tooltipPosition : function(){
|
1086 |
-
return {
|
1087 |
-
x : this.x,
|
1088 |
-
y : this.y
|
1089 |
-
};
|
1090 |
-
},
|
1091 |
-
hasValue: function(){
|
1092 |
-
return isNumber(this.value);
|
1093 |
-
}
|
1094 |
-
});
|
1095 |
-
|
1096 |
-
Chart.Element.extend = inherits;
|
1097 |
-
|
1098 |
-
|
1099 |
-
Chart.Point = Chart.Element.extend({
|
1100 |
-
display: true,
|
1101 |
-
inRange: function(chartX,chartY){
|
1102 |
-
var hitDetectionRange = this.hitDetectionRadius + this.radius;
|
1103 |
-
return ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2));
|
1104 |
-
},
|
1105 |
-
draw : function(){
|
1106 |
-
if (this.display){
|
1107 |
-
var ctx = this.ctx;
|
1108 |
-
ctx.beginPath();
|
1109 |
-
|
1110 |
-
ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
|
1111 |
-
ctx.closePath();
|
1112 |
-
|
1113 |
-
ctx.strokeStyle = this.strokeColor;
|
1114 |
-
ctx.lineWidth = this.strokeWidth;
|
1115 |
-
|
1116 |
-
ctx.fillStyle = this.fillColor;
|
1117 |
-
|
1118 |
-
ctx.fill();
|
1119 |
-
ctx.stroke();
|
1120 |
-
}
|
1121 |
-
|
1122 |
-
|
1123 |
-
//Quick debug for bezier curve splining
|
1124 |
-
//Highlights control points and the line between them.
|
1125 |
-
//Handy for dev - stripped in the min version.
|
1126 |
-
|
1127 |
-
// ctx.save();
|
1128 |
-
// ctx.fillStyle = "black";
|
1129 |
-
// ctx.strokeStyle = "black"
|
1130 |
-
// ctx.beginPath();
|
1131 |
-
// ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2);
|
1132 |
-
// ctx.fill();
|
1133 |
-
|
1134 |
-
// ctx.beginPath();
|
1135 |
-
// ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2);
|
1136 |
-
// ctx.fill();
|
1137 |
-
|
1138 |
-
// ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);
|
1139 |
-
// ctx.lineTo(this.x, this.y);
|
1140 |
-
// ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);
|
1141 |
-
// ctx.stroke();
|
1142 |
-
|
1143 |
-
// ctx.restore();
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
}
|
1148 |
-
});
|
1149 |
-
|
1150 |
-
Chart.Arc = Chart.Element.extend({
|
1151 |
-
inRange : function(chartX,chartY){
|
1152 |
-
|
1153 |
-
var pointRelativePosition = helpers.getAngleFromPoint(this, {
|
1154 |
-
x: chartX,
|
1155 |
-
y: chartY
|
1156 |
-
});
|
1157 |
-
|
1158 |
-
//Check if within the range of the open/close angle
|
1159 |
-
var betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle),
|
1160 |
-
withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius);
|
1161 |
-
|
1162 |
-
return (betweenAngles && withinRadius);
|
1163 |
-
//Ensure within the outside of the arc centre, but inside arc outer
|
1164 |
-
},
|
1165 |
-
tooltipPosition : function(){
|
1166 |
-
var centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2),
|
1167 |
-
rangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius;
|
1168 |
-
return {
|
1169 |
-
x : this.x + (Math.cos(centreAngle) * rangeFromCentre),
|
1170 |
-
y : this.y + (Math.sin(centreAngle) * rangeFromCentre)
|
1171 |
-
};
|
1172 |
-
},
|
1173 |
-
draw : function(animationPercent){
|
1174 |
-
|
1175 |
-
var easingDecimal = animationPercent || 1;
|
1176 |
-
|
1177 |
-
var ctx = this.ctx;
|
1178 |
-
|
1179 |
-
ctx.beginPath();
|
1180 |
-
|
1181 |
-
ctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle);
|
1182 |
-
|
1183 |
-
ctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true);
|
1184 |
-
|
1185 |
-
ctx.closePath();
|
1186 |
-
ctx.strokeStyle = this.strokeColor;
|
1187 |
-
ctx.lineWidth = this.strokeWidth;
|
1188 |
-
|
1189 |
-
ctx.fillStyle = this.fillColor;
|
1190 |
-
|
1191 |
-
ctx.fill();
|
1192 |
-
ctx.lineJoin = 'bevel';
|
1193 |
-
|
1194 |
-
if (this.showStroke){
|
1195 |
-
ctx.stroke();
|
1196 |
-
}
|
1197 |
-
}
|
1198 |
-
});
|
1199 |
-
|
1200 |
-
Chart.Rectangle = Chart.Element.extend({
|
1201 |
-
draw : function(){
|
1202 |
-
var ctx = this.ctx,
|
1203 |
-
halfWidth = this.width/2,
|
1204 |
-
leftX = this.x - halfWidth,
|
1205 |
-
rightX = this.x + halfWidth,
|
1206 |
-
top = this.base - (this.base - this.y),
|
1207 |
-
halfStroke = this.strokeWidth / 2;
|
1208 |
-
|
1209 |
-
// Canvas doesn't allow us to stroke inside the width so we can
|
1210 |
-
// adjust the sizes to fit if we're setting a stroke on the line
|
1211 |
-
if (this.showStroke){
|
1212 |
-
leftX += halfStroke;
|
1213 |
-
rightX -= halfStroke;
|
1214 |
-
top += halfStroke;
|
1215 |
-
}
|
1216 |
-
|
1217 |
-
ctx.beginPath();
|
1218 |
-
|
1219 |
-
ctx.fillStyle = this.fillColor;
|
1220 |
-
ctx.strokeStyle = this.strokeColor;
|
1221 |
-
ctx.lineWidth = this.strokeWidth;
|
1222 |
-
|
1223 |
-
// It'd be nice to keep this class totally generic to any rectangle
|
1224 |
-
// and simply specify which border to miss out.
|
1225 |
-
ctx.moveTo(leftX, this.base);
|
1226 |
-
ctx.lineTo(leftX, top);
|
1227 |
-
ctx.lineTo(rightX, top);
|
1228 |
-
ctx.lineTo(rightX, this.base);
|
1229 |
-
ctx.fill();
|
1230 |
-
if (this.showStroke){
|
1231 |
-
ctx.stroke();
|
1232 |
-
}
|
1233 |
-
},
|
1234 |
-
height : function(){
|
1235 |
-
return this.base - this.y;
|
1236 |
-
},
|
1237 |
-
inRange : function(chartX,chartY){
|
1238 |
-
return (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);
|
1239 |
-
}
|
1240 |
-
});
|
1241 |
-
|
1242 |
-
Chart.Tooltip = Chart.Element.extend({
|
1243 |
-
draw : function(){
|
1244 |
-
|
1245 |
-
var ctx = this.chart.ctx;
|
1246 |
-
|
1247 |
-
ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
|
1248 |
-
|
1249 |
-
this.xAlign = "center";
|
1250 |
-
this.yAlign = "above";
|
1251 |
-
|
1252 |
-
//Distance between the actual element.y position and the start of the tooltip caret
|
1253 |
-
var caretPadding = 2;
|
1254 |
-
|
1255 |
-
var tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,
|
1256 |
-
tooltipRectHeight = this.fontSize + 2*this.yPadding,
|
1257 |
-
tooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;
|
1258 |
-
|
1259 |
-
if (this.x + tooltipWidth/2 >this.chart.width){
|
1260 |
-
this.xAlign = "left";
|
1261 |
-
} else if (this.x - tooltipWidth/2 < 0){
|
1262 |
-
this.xAlign = "right";
|
1263 |
-
}
|
1264 |
-
|
1265 |
-
if (this.y - tooltipHeight < 0){
|
1266 |
-
this.yAlign = "below";
|
1267 |
-
}
|
1268 |
-
|
1269 |
-
|
1270 |
-
var tooltipX = this.x - tooltipWidth/2,
|
1271 |
-
tooltipY = this.y - tooltipHeight;
|
1272 |
-
|
1273 |
-
ctx.fillStyle = this.fillColor;
|
1274 |
-
|
1275 |
-
switch(this.yAlign)
|
1276 |
-
{
|
1277 |
-
case "above":
|
1278 |
-
//Draw a caret above the x/y
|
1279 |
-
ctx.beginPath();
|
1280 |
-
ctx.moveTo(this.x,this.y - caretPadding);
|
1281 |
-
ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));
|
1282 |
-
ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));
|
1283 |
-
ctx.closePath();
|
1284 |
-
ctx.fill();
|
1285 |
-
break;
|
1286 |
-
case "below":
|
1287 |
-
tooltipY = this.y + caretPadding + this.caretHeight;
|
1288 |
-
//Draw a caret below the x/y
|
1289 |
-
ctx.beginPath();
|
1290 |
-
ctx.moveTo(this.x, this.y + caretPadding);
|
1291 |
-
ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);
|
1292 |
-
ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);
|
1293 |
-
ctx.closePath();
|
1294 |
-
ctx.fill();
|
1295 |
-
break;
|
1296 |
-
}
|
1297 |
-
|
1298 |
-
switch(this.xAlign)
|
1299 |
-
{
|
1300 |
-
case "left":
|
1301 |
-
tooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);
|
1302 |
-
break;
|
1303 |
-
case "right":
|
1304 |
-
tooltipX = this.x - (this.cornerRadius + this.caretHeight);
|
1305 |
-
break;
|
1306 |
-
}
|
1307 |
-
|
1308 |
-
drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);
|
1309 |
-
|
1310 |
-
ctx.fill();
|
1311 |
-
|
1312 |
-
ctx.fillStyle = this.textColor;
|
1313 |
-
ctx.textAlign = "center";
|
1314 |
-
ctx.textBaseline = "middle";
|
1315 |
-
ctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);
|
1316 |
-
}
|
1317 |
-
});
|
1318 |
-
|
1319 |
-
Chart.MultiTooltip = Chart.Element.extend({
|
1320 |
-
initialize : function(){
|
1321 |
-
this.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
|
1322 |
-
|
1323 |
-
this.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily);
|
1324 |
-
|
1325 |
-
this.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5;
|
1326 |
-
|
1327 |
-
this.ctx.font = this.titleFont;
|
1328 |
-
|
1329 |
-
var titleWidth = this.ctx.measureText(this.title).width,
|
1330 |
-
//Label has a legend square as well so account for this.
|
1331 |
-
labelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,
|
1332 |
-
longestTextWidth = max([labelWidth,titleWidth]);
|
1333 |
-
|
1334 |
-
this.width = longestTextWidth + (this.xPadding*2);
|
1335 |
-
|
1336 |
-
|
1337 |
-
var halfHeight = this.height/2;
|
1338 |
-
|
1339 |
-
//Check to ensure the height will fit on the canvas
|
1340 |
-
//The three is to buffer form the very
|
1341 |
-
if (this.y - halfHeight < 0 ){
|
1342 |
-
this.y = halfHeight;
|
1343 |
-
} else if (this.y + halfHeight > this.chart.height){
|
1344 |
-
this.y = this.chart.height - halfHeight;
|
1345 |
-
}
|
1346 |
-
|
1347 |
-
//Decide whether to align left or right based on position on canvas
|
1348 |
-
if (this.x > this.chart.width/2){
|
1349 |
-
this.x -= this.xOffset + this.width;
|
1350 |
-
} else {
|
1351 |
-
this.x += this.xOffset;
|
1352 |
-
}
|
1353 |
-
|
1354 |
-
|
1355 |
-
},
|
1356 |
-
getLineHeight : function(index){
|
1357 |
-
var baseLineHeight = this.y - (this.height/2) + this.yPadding,
|
1358 |
-
afterTitleIndex = index-1;
|
1359 |
-
|
1360 |
-
//If the index is zero, we're getting the title
|
1361 |
-
if (index === 0){
|
1362 |
-
return baseLineHeight + this.titleFontSize/2;
|
1363 |
-
} else{
|
1364 |
-
return baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5;
|
1365 |
-
}
|
1366 |
-
|
1367 |
-
},
|
1368 |
-
draw : function(){
|
1369 |
-
drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);
|
1370 |
-
var ctx = this.ctx;
|
1371 |
-
ctx.fillStyle = this.fillColor;
|
1372 |
-
ctx.fill();
|
1373 |
-
ctx.closePath();
|
1374 |
-
|
1375 |
-
ctx.textAlign = "left";
|
1376 |
-
ctx.textBaseline = "middle";
|
1377 |
-
ctx.fillStyle = this.titleTextColor;
|
1378 |
-
ctx.font = this.titleFont;
|
1379 |
-
|
1380 |
-
ctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));
|
1381 |
-
|
1382 |
-
ctx.font = this.font;
|
1383 |
-
helpers.each(this.labels,function(label,index){
|
1384 |
-
ctx.fillStyle = this.textColor;
|
1385 |
-
ctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));
|
1386 |
-
|
1387 |
-
//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)
|
1388 |
-
//ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1389 |
-
//Instead we'll make a white filled block to put the legendColour palette over.
|
1390 |
-
|
1391 |
-
ctx.fillStyle = this.legendColorBackground;
|
1392 |
-
ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1393 |
-
|
1394 |
-
ctx.fillStyle = this.legendColors[index].fill;
|
1395 |
-
ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1396 |
-
|
1397 |
-
|
1398 |
-
},this);
|
1399 |
-
}
|
1400 |
-
});
|
1401 |
-
|
1402 |
-
Chart.Scale = Chart.Element.extend({
|
1403 |
-
initialize : function(){
|
1404 |
-
this.fit();
|
1405 |
-
},
|
1406 |
-
buildYLabels : function(){
|
1407 |
-
this.yLabels = [];
|
1408 |
-
|
1409 |
-
var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
|
1410 |
-
|
1411 |
-
for (var i=0; i<=this.steps; i++){
|
1412 |
-
this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
|
1413 |
-
}
|
1414 |
-
this.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0;
|
1415 |
-
},
|
1416 |
-
addXLabel : function(label){
|
1417 |
-
this.xLabels.push(label);
|
1418 |
-
this.valuesCount++;
|
1419 |
-
this.fit();
|
1420 |
-
},
|
1421 |
-
removeXLabel : function(){
|
1422 |
-
this.xLabels.shift();
|
1423 |
-
this.valuesCount--;
|
1424 |
-
this.fit();
|
1425 |
-
},
|
1426 |
-
// Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use
|
1427 |
-
fit: function(){
|
1428 |
-
// First we need the width of the yLabels, assuming the xLabels aren't rotated
|
1429 |
-
|
1430 |
-
// To do that we need the base line at the top and base of the chart, assuming there is no x label rotation
|
1431 |
-
this.startPoint = (this.display) ? this.fontSize : 0;
|
1432 |
-
this.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels
|
1433 |
-
|
1434 |
-
// Apply padding settings to the start and end point.
|
1435 |
-
this.startPoint += this.padding;
|
1436 |
-
this.endPoint -= this.padding;
|
1437 |
-
|
1438 |
-
// Cache the starting height, so can determine if we need to recalculate the scale yAxis
|
1439 |
-
var cachedHeight = this.endPoint - this.startPoint,
|
1440 |
-
cachedYLabelWidth;
|
1441 |
-
|
1442 |
-
// Build the current yLabels so we have an idea of what size they'll be to start
|
1443 |
-
/*
|
1444 |
-
* This sets what is returned from calculateScaleRange as static properties of this class:
|
1445 |
-
*
|
1446 |
-
this.steps;
|
1447 |
-
this.stepValue;
|
1448 |
-
this.min;
|
1449 |
-
this.max;
|
1450 |
-
*
|
1451 |
-
*/
|
1452 |
-
this.calculateYRange(cachedHeight);
|
1453 |
-
|
1454 |
-
// With these properties set we can now build the array of yLabels
|
1455 |
-
// and also the width of the largest yLabel
|
1456 |
-
this.buildYLabels();
|
1457 |
-
|
1458 |
-
this.calculateXLabelRotation();
|
1459 |
-
|
1460 |
-
while((cachedHeight > this.endPoint - this.startPoint)){
|
1461 |
-
cachedHeight = this.endPoint - this.startPoint;
|
1462 |
-
cachedYLabelWidth = this.yLabelWidth;
|
1463 |
-
|
1464 |
-
this.calculateYRange(cachedHeight);
|
1465 |
-
this.buildYLabels();
|
1466 |
-
|
1467 |
-
// Only go through the xLabel loop again if the yLabel width has changed
|
1468 |
-
if (cachedYLabelWidth < this.yLabelWidth){
|
1469 |
-
this.calculateXLabelRotation();
|
1470 |
-
}
|
1471 |
-
}
|
1472 |
-
|
1473 |
-
},
|
1474 |
-
calculateXLabelRotation : function(){
|
1475 |
-
//Get the width of each grid by calculating the difference
|
1476 |
-
//between x offsets between 0 and 1.
|
1477 |
-
|
1478 |
-
this.ctx.font = this.font;
|
1479 |
-
|
1480 |
-
var firstWidth = this.ctx.measureText(this.xLabels[0]).width,
|
1481 |
-
lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,
|
1482 |
-
firstRotated,
|
1483 |
-
lastRotated;
|
1484 |
-
|
1485 |
-
|
1486 |
-
this.xScalePaddingRight = lastWidth/2 + 3;
|
1487 |
-
this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10;
|
1488 |
-
|
1489 |
-
this.xLabelRotation = 0;
|
1490 |
-
if (this.display){
|
1491 |
-
var originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),
|
1492 |
-
cosRotation,
|
1493 |
-
firstRotatedWidth;
|
1494 |
-
this.xLabelWidth = originalLabelWidth;
|
1495 |
-
//Allow 3 pixels x2 padding either side for label readability
|
1496 |
-
var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;
|
1497 |
-
|
1498 |
-
//Max label rotate should be 90 - also act as a loop counter
|
1499 |
-
while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){
|
1500 |
-
cosRotation = Math.cos(toRadians(this.xLabelRotation));
|
1501 |
-
|
1502 |
-
firstRotated = cosRotation * firstWidth;
|
1503 |
-
lastRotated = cosRotation * lastWidth;
|
1504 |
-
|
1505 |
-
// We're right aligning the text now.
|
1506 |
-
if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8){
|
1507 |
-
this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
|
1508 |
-
}
|
1509 |
-
this.xScalePaddingRight = this.fontSize/2;
|
1510 |
-
|
1511 |
-
|
1512 |
-
this.xLabelRotation++;
|
1513 |
-
this.xLabelWidth = cosRotation * originalLabelWidth;
|
1514 |
-
|
1515 |
-
}
|
1516 |
-
if (this.xLabelRotation > 0){
|
1517 |
-
this.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;
|
1518 |
-
}
|
1519 |
-
}
|
1520 |
-
else{
|
1521 |
-
this.xLabelWidth = 0;
|
1522 |
-
this.xScalePaddingRight = this.padding;
|
1523 |
-
this.xScalePaddingLeft = this.padding;
|
1524 |
-
}
|
1525 |
-
|
1526 |
-
},
|
1527 |
-
// Needs to be overidden in each Chart type
|
1528 |
-
// Otherwise we need to pass all the data into the scale class
|
1529 |
-
calculateYRange: noop,
|
1530 |
-
drawingArea: function(){
|
1531 |
-
return this.startPoint - this.endPoint;
|
1532 |
-
},
|
1533 |
-
calculateY : function(value){
|
1534 |
-
var scalingFactor = this.drawingArea() / (this.min - this.max);
|
1535 |
-
return this.endPoint - (scalingFactor * (value - this.min));
|
1536 |
-
},
|
1537 |
-
calculateX : function(index){
|
1538 |
-
var isRotated = (this.xLabelRotation > 0),
|
1539 |
-
// innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,
|
1540 |
-
innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
|
1541 |
-
valueWidth = innerWidth/(this.valuesCount - ((this.offsetGridLines) ? 0 : 1)),
|
1542 |
-
valueOffset = (valueWidth * index) + this.xScalePaddingLeft;
|
1543 |
-
|
1544 |
-
if (this.offsetGridLines){
|
1545 |
-
valueOffset += (valueWidth/2);
|
1546 |
-
}
|
1547 |
-
|
1548 |
-
return Math.round(valueOffset);
|
1549 |
-
},
|
1550 |
-
update : function(newProps){
|
1551 |
-
helpers.extend(this, newProps);
|
1552 |
-
this.fit();
|
1553 |
-
},
|
1554 |
-
draw : function(){
|
1555 |
-
var ctx = this.ctx,
|
1556 |
-
yLabelGap = (this.endPoint - this.startPoint) / this.steps,
|
1557 |
-
xStart = Math.round(this.xScalePaddingLeft);
|
1558 |
-
if (this.display){
|
1559 |
-
ctx.fillStyle = this.textColor;
|
1560 |
-
ctx.font = this.font;
|
1561 |
-
each(this.yLabels,function(labelString,index){
|
1562 |
-
var yLabelCenter = this.endPoint - (yLabelGap * index),
|
1563 |
-
linePositionY = Math.round(yLabelCenter);
|
1564 |
-
|
1565 |
-
ctx.textAlign = "right";
|
1566 |
-
ctx.textBaseline = "middle";
|
1567 |
-
if (this.showLabels){
|
1568 |
-
ctx.fillText(labelString,xStart - 10,yLabelCenter);
|
1569 |
-
}
|
1570 |
-
ctx.beginPath();
|
1571 |
-
if (index > 0){
|
1572 |
-
// This is a grid line in the centre, so drop that
|
1573 |
-
ctx.lineWidth = this.gridLineWidth;
|
1574 |
-
ctx.strokeStyle = this.gridLineColor;
|
1575 |
-
} else {
|
1576 |
-
// This is the first line on the scale
|
1577 |
-
ctx.lineWidth = this.lineWidth;
|
1578 |
-
ctx.strokeStyle = this.lineColor;
|
1579 |
-
}
|
1580 |
-
|
1581 |
-
linePositionY += helpers.aliasPixel(ctx.lineWidth);
|
1582 |
-
|
1583 |
-
ctx.moveTo(xStart, linePositionY);
|
1584 |
-
ctx.lineTo(this.width, linePositionY);
|
1585 |
-
ctx.stroke();
|
1586 |
-
ctx.closePath();
|
1587 |
-
|
1588 |
-
ctx.lineWidth = this.lineWidth;
|
1589 |
-
ctx.strokeStyle = this.lineColor;
|
1590 |
-
ctx.beginPath();
|
1591 |
-
ctx.moveTo(xStart - 5, linePositionY);
|
1592 |
-
ctx.lineTo(xStart, linePositionY);
|
1593 |
-
ctx.stroke();
|
1594 |
-
ctx.closePath();
|
1595 |
-
|
1596 |
-
},this);
|
1597 |
-
|
1598 |
-
each(this.xLabels,function(label,index){
|
1599 |
-
var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
|
1600 |
-
// Check to see if line/bar here and decide where to place the line
|
1601 |
-
linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
|
1602 |
-
isRotated = (this.xLabelRotation > 0);
|
1603 |
-
|
1604 |
-
ctx.beginPath();
|
1605 |
-
|
1606 |
-
if (index > 0){
|
1607 |
-
// This is a grid line in the centre, so drop that
|
1608 |
-
ctx.lineWidth = this.gridLineWidth;
|
1609 |
-
ctx.strokeStyle = this.gridLineColor;
|
1610 |
-
} else {
|
1611 |
-
// This is the first line on the scale
|
1612 |
-
ctx.lineWidth = this.lineWidth;
|
1613 |
-
ctx.strokeStyle = this.lineColor;
|
1614 |
-
}
|
1615 |
-
ctx.moveTo(linePos,this.endPoint);
|
1616 |
-
ctx.lineTo(linePos,this.startPoint - 3);
|
1617 |
-
ctx.stroke();
|
1618 |
-
ctx.closePath();
|
1619 |
-
|
1620 |
-
|
1621 |
-
ctx.lineWidth = this.lineWidth;
|
1622 |
-
ctx.strokeStyle = this.lineColor;
|
1623 |
-
|
1624 |
-
|
1625 |
-
// Small lines at the bottom of the base grid line
|
1626 |
-
ctx.beginPath();
|
1627 |
-
ctx.moveTo(linePos,this.endPoint);
|
1628 |
-
ctx.lineTo(linePos,this.endPoint + 5);
|
1629 |
-
ctx.stroke();
|
1630 |
-
ctx.closePath();
|
1631 |
-
|
1632 |
-
ctx.save();
|
1633 |
-
ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);
|
1634 |
-
ctx.rotate(toRadians(this.xLabelRotation)*-1);
|
1635 |
-
ctx.font = this.font;
|
1636 |
-
ctx.textAlign = (isRotated) ? "right" : "center";
|
1637 |
-
ctx.textBaseline = (isRotated) ? "middle" : "top";
|
1638 |
-
ctx.fillText(label, 0, 0);
|
1639 |
-
ctx.restore();
|
1640 |
-
},this);
|
1641 |
-
|
1642 |
-
}
|
1643 |
-
}
|
1644 |
-
|
1645 |
-
});
|
1646 |
-
|
1647 |
-
Chart.RadialScale = Chart.Element.extend({
|
1648 |
-
initialize: function(){
|
1649 |
-
this.size = min([this.height, this.width]);
|
1650 |
-
this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
|
1651 |
-
},
|
1652 |
-
calculateCenterOffset: function(value){
|
1653 |
-
// Take into account half font size + the yPadding of the top value
|
1654 |
-
var scalingFactor = this.drawingArea / (this.max - this.min);
|
1655 |
-
|
1656 |
-
return (value - this.min) * scalingFactor;
|
1657 |
-
},
|
1658 |
-
update : function(){
|
1659 |
-
if (!this.lineArc){
|
1660 |
-
this.setScaleSize();
|
1661 |
-
} else {
|
1662 |
-
this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
|
1663 |
-
}
|
1664 |
-
this.buildYLabels();
|
1665 |
-
},
|
1666 |
-
buildYLabels: function(){
|
1667 |
-
this.yLabels = [];
|
1668 |
-
|
1669 |
-
var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
|
1670 |
-
|
1671 |
-
for (var i=0; i<=this.steps; i++){
|
1672 |
-
this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
|
1673 |
-
}
|
1674 |
-
},
|
1675 |
-
getCircumference : function(){
|
1676 |
-
return ((Math.PI*2) / this.valuesCount);
|
1677 |
-
},
|
1678 |
-
setScaleSize: function(){
|
1679 |
-
/*
|
1680 |
-
* Right, this is really confusing and there is a lot of maths going on here
|
1681 |
-
* The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
|
1682 |
-
*
|
1683 |
-
* Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
|
1684 |
-
*
|
1685 |
-
* Solution:
|
1686 |
-
*
|
1687 |
-
* We assume the radius of the polygon is half the size of the canvas at first
|
1688 |
-
* at each index we check if the text overlaps.
|
1689 |
-
*
|
1690 |
-
* Where it does, we store that angle and that index.
|
1691 |
-
*
|
1692 |
-
* After finding the largest index and angle we calculate how much we need to remove
|
1693 |
-
* from the shape radius to move the point inwards by that x.
|
1694 |
-
*
|
1695 |
-
* We average the left and right distances to get the maximum shape radius that can fit in the box
|
1696 |
-
* along with labels.
|
1697 |
-
*
|
1698 |
-
* Once we have that, we can find the centre point for the chart, by taking the x text protrusion
|
1699 |
-
* on each side, removing that from the size, halving it and adding the left x protrusion width.
|
1700 |
-
*
|
1701 |
-
* This will mean we have a shape fitted to the canvas, as large as it can be with the labels
|
1702 |
-
* and position it in the most space efficient manner
|
1703 |
-
*
|
1704 |
-
* https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
|
1705 |
-
*/
|
1706 |
-
|
1707 |
-
|
1708 |
-
// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
|
1709 |
-
// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
|
1710 |
-
var largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),
|
1711 |
-
pointPosition,
|
1712 |
-
i,
|
1713 |
-
textWidth,
|
1714 |
-
halfTextWidth,
|
1715 |
-
furthestRight = this.width,
|
1716 |
-
furthestRightIndex,
|
1717 |
-
furthestRightAngle,
|
1718 |
-
furthestLeft = 0,
|
1719 |
-
furthestLeftIndex,
|
1720 |
-
furthestLeftAngle,
|
1721 |
-
xProtrusionLeft,
|
1722 |
-
xProtrusionRight,
|
1723 |
-
radiusReductionRight,
|
1724 |
-
radiusReductionLeft,
|
1725 |
-
maxWidthRadius;
|
1726 |
-
this.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
|
1727 |
-
for (i=0;i<this.valuesCount;i++){
|
1728 |
-
// 5px to space the text slightly out - similar to what we do in the draw function.
|
1729 |
-
pointPosition = this.getPointPosition(i, largestPossibleRadius);
|
1730 |
-
textWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;
|
1731 |
-
if (i === 0 || i === this.valuesCount/2){
|
1732 |
-
// If we're at index zero, or exactly the middle, we're at exactly the top/bottom
|
1733 |
-
// of the radar chart, so text will be aligned centrally, so we'll half it and compare
|
1734 |
-
// w/left and right text sizes
|
1735 |
-
halfTextWidth = textWidth/2;
|
1736 |
-
if (pointPosition.x + halfTextWidth > furthestRight) {
|
1737 |
-
furthestRight = pointPosition.x + halfTextWidth;
|
1738 |
-
furthestRightIndex = i;
|
1739 |
-
}
|
1740 |
-
if (pointPosition.x - halfTextWidth < furthestLeft) {
|
1741 |
-
furthestLeft = pointPosition.x - halfTextWidth;
|
1742 |
-
furthestLeftIndex = i;
|
1743 |
-
}
|
1744 |
-
}
|
1745 |
-
else if (i < this.valuesCount/2) {
|
1746 |
-
// Less than half the values means we'll left align the text
|
1747 |
-
if (pointPosition.x + textWidth > furthestRight) {
|
1748 |
-
furthestRight = pointPosition.x + textWidth;
|
1749 |
-
furthestRightIndex = i;
|
1750 |
-
}
|
1751 |
-
}
|
1752 |
-
else if (i > this.valuesCount/2){
|
1753 |
-
// More than half the values means we'll right align the text
|
1754 |
-
if (pointPosition.x - textWidth < furthestLeft) {
|
1755 |
-
furthestLeft = pointPosition.x - textWidth;
|
1756 |
-
furthestLeftIndex = i;
|
1757 |
-
}
|
1758 |
-
}
|
1759 |
-
}
|
1760 |
-
|
1761 |
-
xProtrusionLeft = furthestLeft;
|
1762 |
-
|
1763 |
-
xProtrusionRight = Math.ceil(furthestRight - this.width);
|
1764 |
-
|
1765 |
-
furthestRightAngle = this.getIndexAngle(furthestRightIndex);
|
1766 |
-
|
1767 |
-
furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);
|
1768 |
-
|
1769 |
-
radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);
|
1770 |
-
|
1771 |
-
radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);
|
1772 |
-
|
1773 |
-
// Ensure we actually need to reduce the size of the chart
|
1774 |
-
radiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;
|
1775 |
-
radiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;
|
1776 |
-
|
1777 |
-
this.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;
|
1778 |
-
|
1779 |
-
//this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])
|
1780 |
-
this.setCenterPoint(radiusReductionLeft, radiusReductionRight);
|
1781 |
-
|
1782 |
-
},
|
1783 |
-
setCenterPoint: function(leftMovement, rightMovement){
|
1784 |
-
|
1785 |
-
var maxRight = this.width - rightMovement - this.drawingArea,
|
1786 |
-
maxLeft = leftMovement + this.drawingArea;
|
1787 |
-
|
1788 |
-
this.xCenter = (maxLeft + maxRight)/2;
|
1789 |
-
// Always vertically in the centre as the text height doesn't change
|
1790 |
-
this.yCenter = (this.height/2);
|
1791 |
-
},
|
1792 |
-
|
1793 |
-
getIndexAngle : function(index){
|
1794 |
-
var angleMultiplier = (Math.PI * 2) / this.valuesCount;
|
1795 |
-
// Start from the top instead of right, so remove a quarter of the circle
|
1796 |
-
|
1797 |
-
return index * angleMultiplier - (Math.PI/2);
|
1798 |
-
},
|
1799 |
-
getPointPosition : function(index, distanceFromCenter){
|
1800 |
-
var thisAngle = this.getIndexAngle(index);
|
1801 |
-
return {
|
1802 |
-
x : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,
|
1803 |
-
y : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter
|
1804 |
-
};
|
1805 |
-
},
|
1806 |
-
draw: function(){
|
1807 |
-
if (this.display){
|
1808 |
-
var ctx = this.ctx;
|
1809 |
-
each(this.yLabels, function(label, index){
|
1810 |
-
// Don't draw a centre value
|
1811 |
-
if (index > 0){
|
1812 |
-
var yCenterOffset = index * (this.drawingArea/this.steps),
|
1813 |
-
yHeight = this.yCenter - yCenterOffset,
|
1814 |
-
pointPosition;
|
1815 |
-
|
1816 |
-
// Draw circular lines around the scale
|
1817 |
-
if (this.lineWidth > 0){
|
1818 |
-
ctx.strokeStyle = this.lineColor;
|
1819 |
-
ctx.lineWidth = this.lineWidth;
|
1820 |
-
|
1821 |
-
if(this.lineArc){
|
1822 |
-
ctx.beginPath();
|
1823 |
-
ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);
|
1824 |
-
ctx.closePath();
|
1825 |
-
ctx.stroke();
|
1826 |
-
} else{
|
1827 |
-
ctx.beginPath();
|
1828 |
-
for (var i=0;i<this.valuesCount;i++)
|
1829 |
-
{
|
1830 |
-
pointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));
|
1831 |
-
if (i === 0){
|
1832 |
-
ctx.moveTo(pointPosition.x, pointPosition.y);
|
1833 |
-
} else {
|
1834 |
-
ctx.lineTo(pointPosition.x, pointPosition.y);
|
1835 |
-
}
|
1836 |
-
}
|
1837 |
-
ctx.closePath();
|
1838 |
-
ctx.stroke();
|
1839 |
-
}
|
1840 |
-
}
|
1841 |
-
if(this.showLabels){
|
1842 |
-
ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
|
1843 |
-
if (this.showLabelBackdrop){
|
1844 |
-
var labelWidth = ctx.measureText(label).width;
|
1845 |
-
ctx.fillStyle = this.backdropColor;
|
1846 |
-
ctx.fillRect(
|
1847 |
-
this.xCenter - labelWidth/2 - this.backdropPaddingX,
|
1848 |
-
yHeight - this.fontSize/2 - this.backdropPaddingY,
|
1849 |
-
labelWidth + this.backdropPaddingX*2,
|
1850 |
-
this.fontSize + this.backdropPaddingY*2
|
1851 |
-
);
|
1852 |
-
}
|
1853 |
-
ctx.textAlign = 'center';
|
1854 |
-
ctx.textBaseline = "middle";
|
1855 |
-
ctx.fillStyle = this.fontColor;
|
1856 |
-
ctx.fillText(label, this.xCenter, yHeight);
|
1857 |
-
}
|
1858 |
-
}
|
1859 |
-
}, this);
|
1860 |
-
|
1861 |
-
if (!this.lineArc){
|
1862 |
-
ctx.lineWidth = this.angleLineWidth;
|
1863 |
-
ctx.strokeStyle = this.angleLineColor;
|
1864 |
-
for (var i = this.valuesCount - 1; i >= 0; i--) {
|
1865 |
-
if (this.angleLineWidth > 0){
|
1866 |
-
var outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max));
|
1867 |
-
ctx.beginPath();
|
1868 |
-
ctx.moveTo(this.xCenter, this.yCenter);
|
1869 |
-
ctx.lineTo(outerPosition.x, outerPosition.y);
|
1870 |
-
ctx.stroke();
|
1871 |
-
ctx.closePath();
|
1872 |
-
}
|
1873 |
-
// Extra 3px out for some label spacing
|
1874 |
-
var pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5);
|
1875 |
-
ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
|
1876 |
-
ctx.fillStyle = this.pointLabelFontColor;
|
1877 |
-
|
1878 |
-
var labelsCount = this.labels.length,
|
1879 |
-
halfLabelsCount = this.labels.length/2,
|
1880 |
-
quarterLabelsCount = halfLabelsCount/2,
|
1881 |
-
upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
|
1882 |
-
exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
|
1883 |
-
if (i === 0){
|
1884 |
-
ctx.textAlign = 'center';
|
1885 |
-
} else if(i === halfLabelsCount){
|
1886 |
-
ctx.textAlign = 'center';
|
1887 |
-
} else if (i < halfLabelsCount){
|
1888 |
-
ctx.textAlign = 'left';
|
1889 |
-
} else {
|
1890 |
-
ctx.textAlign = 'right';
|
1891 |
-
}
|
1892 |
-
|
1893 |
-
// Set the correct text baseline based on outer positioning
|
1894 |
-
if (exactQuarter){
|
1895 |
-
ctx.textBaseline = 'middle';
|
1896 |
-
} else if (upperHalf){
|
1897 |
-
ctx.textBaseline = 'bottom';
|
1898 |
-
} else {
|
1899 |
-
ctx.textBaseline = 'top';
|
1900 |
-
}
|
1901 |
-
|
1902 |
-
ctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);
|
1903 |
-
}
|
1904 |
-
}
|
1905 |
-
}
|
1906 |
-
}
|
1907 |
-
});
|
1908 |
-
|
1909 |
-
// Attach global event to resize each chart instance when the browser resizes
|
1910 |
-
helpers.addEvent(window, "resize", (function(){
|
1911 |
-
// Basic debounce of resize function so it doesn't hurt performance when resizing browser.
|
1912 |
-
var timeout;
|
1913 |
-
return function(){
|
1914 |
-
clearTimeout(timeout);
|
1915 |
-
timeout = setTimeout(function(){
|
1916 |
-
each(Chart.instances,function(instance){
|
1917 |
-
// If the responsive flag is set in the chart instance config
|
1918 |
-
// Cascade the resize event down to the chart.
|
1919 |
-
if (instance.options.responsive){
|
1920 |
-
instance.resize(instance.render, true);
|
1921 |
-
}
|
1922 |
-
});
|
1923 |
-
}, 50);
|
1924 |
-
};
|
1925 |
-
})());
|
1926 |
-
|
1927 |
-
|
1928 |
-
if (amd) {
|
1929 |
-
define(function(){
|
1930 |
-
return Chart;
|
1931 |
-
});
|
1932 |
-
} else if (typeof module === 'object' && module.exports) {
|
1933 |
-
module.exports = Chart;
|
1934 |
-
}
|
1935 |
-
|
1936 |
-
root.Chart = Chart;
|
1937 |
-
|
1938 |
-
Chart.noConflict = function(){
|
1939 |
-
root.Chart = previous;
|
1940 |
-
return Chart;
|
1941 |
-
};
|
1942 |
-
|
1943 |
-
}).call(this);
|
1944 |
-
|
1945 |
-
(function(){
|
1946 |
-
"use strict";
|
1947 |
-
|
1948 |
-
var root = this,
|
1949 |
-
Chart = root.Chart,
|
1950 |
-
helpers = Chart.helpers;
|
1951 |
-
|
1952 |
-
|
1953 |
-
var defaultConfig = {
|
1954 |
-
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
|
1955 |
-
scaleBeginAtZero : true,
|
1956 |
-
|
1957 |
-
//Boolean - Whether grid lines are shown across the chart
|
1958 |
-
scaleShowGridLines : true,
|
1959 |
-
|
1960 |
-
//String - Colour of the grid lines
|
1961 |
-
scaleGridLineColor : "rgba(0,0,0,.05)",
|
1962 |
-
|
1963 |
-
//Number - Width of the grid lines
|
1964 |
-
scaleGridLineWidth : 1,
|
1965 |
-
|
1966 |
-
//Boolean - If there is a stroke on each bar
|
1967 |
-
barShowStroke : true,
|
1968 |
-
|
1969 |
-
//Number - Pixel width of the bar stroke
|
1970 |
-
barStrokeWidth : 2,
|
1971 |
-
|
1972 |
-
//Number - Spacing between each of the X value sets
|
1973 |
-
barValueSpacing : 5,
|
1974 |
-
|
1975 |
-
//Number - Spacing between data sets within X values
|
1976 |
-
barDatasetSpacing : 1,
|
1977 |
-
|
1978 |
-
//String - A legend template
|
1979 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
1980 |
-
|
1981 |
-
};
|
1982 |
-
|
1983 |
-
|
1984 |
-
Chart.Type.extend({
|
1985 |
-
name: "Bar",
|
1986 |
-
defaults : defaultConfig,
|
1987 |
-
initialize: function(data){
|
1988 |
-
|
1989 |
-
//Expose options as a scope variable here so we can access it in the ScaleClass
|
1990 |
-
var options = this.options;
|
1991 |
-
|
1992 |
-
this.ScaleClass = Chart.Scale.extend({
|
1993 |
-
offsetGridLines : true,
|
1994 |
-
calculateBarX : function(datasetCount, datasetIndex, barIndex){
|
1995 |
-
//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
|
1996 |
-
var xWidth = this.calculateBaseWidth(),
|
1997 |
-
xAbsolute = this.calculateX(barIndex) - (xWidth/2),
|
1998 |
-
barWidth = this.calculateBarWidth(datasetCount);
|
1999 |
-
|
2000 |
-
return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;
|
2001 |
-
},
|
2002 |
-
calculateBaseWidth : function(){
|
2003 |
-
return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
|
2004 |
-
},
|
2005 |
-
calculateBarWidth : function(datasetCount){
|
2006 |
-
//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
|
2007 |
-
var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);
|
2008 |
-
|
2009 |
-
return (baseWidth / datasetCount);
|
2010 |
-
}
|
2011 |
-
});
|
2012 |
-
|
2013 |
-
this.datasets = [];
|
2014 |
-
|
2015 |
-
//Set up tooltip events on the chart
|
2016 |
-
if (this.options.showTooltips){
|
2017 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
2018 |
-
var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
|
2019 |
-
|
2020 |
-
this.eachBars(function(bar){
|
2021 |
-
bar.restore(['fillColor', 'strokeColor']);
|
2022 |
-
});
|
2023 |
-
helpers.each(activeBars, function(activeBar){
|
2024 |
-
activeBar.fillColor = activeBar.highlightFill;
|
2025 |
-
activeBar.strokeColor = activeBar.highlightStroke;
|
2026 |
-
});
|
2027 |
-
this.showTooltip(activeBars);
|
2028 |
-
});
|
2029 |
-
}
|
2030 |
-
|
2031 |
-
//Declare the extension of the default point, to cater for the options passed in to the constructor
|
2032 |
-
this.BarClass = Chart.Rectangle.extend({
|
2033 |
-
strokeWidth : this.options.barStrokeWidth,
|
2034 |
-
showStroke : this.options.barShowStroke,
|
2035 |
-
ctx : this.chart.ctx
|
2036 |
-
});
|
2037 |
-
|
2038 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
2039 |
-
helpers.each(data.datasets,function(dataset,datasetIndex){
|
2040 |
-
|
2041 |
-
var datasetObject = {
|
2042 |
-
label : dataset.label || null,
|
2043 |
-
fillColor : dataset.fillColor,
|
2044 |
-
strokeColor : dataset.strokeColor,
|
2045 |
-
bars : []
|
2046 |
-
};
|
2047 |
-
|
2048 |
-
this.datasets.push(datasetObject);
|
2049 |
-
|
2050 |
-
helpers.each(dataset.data,function(dataPoint,index){
|
2051 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
2052 |
-
datasetObject.bars.push(new this.BarClass({
|
2053 |
-
value : dataPoint,
|
2054 |
-
label : data.labels[index],
|
2055 |
-
datasetLabel: dataset.label,
|
2056 |
-
strokeColor : dataset.strokeColor,
|
2057 |
-
fillColor : dataset.fillColor,
|
2058 |
-
highlightFill : dataset.highlightFill || dataset.fillColor,
|
2059 |
-
highlightStroke : dataset.highlightStroke || dataset.strokeColor
|
2060 |
-
}));
|
2061 |
-
},this);
|
2062 |
-
|
2063 |
-
},this);
|
2064 |
-
|
2065 |
-
this.buildScale(data.labels);
|
2066 |
-
|
2067 |
-
this.BarClass.prototype.base = this.scale.endPoint;
|
2068 |
-
|
2069 |
-
this.eachBars(function(bar, index, datasetIndex){
|
2070 |
-
helpers.extend(bar, {
|
2071 |
-
width : this.scale.calculateBarWidth(this.datasets.length),
|
2072 |
-
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
|
2073 |
-
y: this.scale.endPoint
|
2074 |
-
});
|
2075 |
-
bar.save();
|
2076 |
-
}, this);
|
2077 |
-
|
2078 |
-
this.render();
|
2079 |
-
},
|
2080 |
-
update : function(){
|
2081 |
-
this.scale.update();
|
2082 |
-
// Reset any highlight colours before updating.
|
2083 |
-
helpers.each(this.activeElements, function(activeElement){
|
2084 |
-
activeElement.restore(['fillColor', 'strokeColor']);
|
2085 |
-
});
|
2086 |
-
|
2087 |
-
this.eachBars(function(bar){
|
2088 |
-
bar.save();
|
2089 |
-
});
|
2090 |
-
this.render();
|
2091 |
-
},
|
2092 |
-
eachBars : function(callback){
|
2093 |
-
helpers.each(this.datasets,function(dataset, datasetIndex){
|
2094 |
-
helpers.each(dataset.bars, callback, this, datasetIndex);
|
2095 |
-
},this);
|
2096 |
-
},
|
2097 |
-
getBarsAtEvent : function(e){
|
2098 |
-
var barsArray = [],
|
2099 |
-
eventPosition = helpers.getRelativePosition(e),
|
2100 |
-
datasetIterator = function(dataset){
|
2101 |
-
barsArray.push(dataset.bars[barIndex]);
|
2102 |
-
},
|
2103 |
-
barIndex;
|
2104 |
-
|
2105 |
-
for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
|
2106 |
-
for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
|
2107 |
-
if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
|
2108 |
-
helpers.each(this.datasets, datasetIterator);
|
2109 |
-
return barsArray;
|
2110 |
-
}
|
2111 |
-
}
|
2112 |
-
}
|
2113 |
-
|
2114 |
-
return barsArray;
|
2115 |
-
},
|
2116 |
-
buildScale : function(labels){
|
2117 |
-
var self = this;
|
2118 |
-
|
2119 |
-
var dataTotal = function(){
|
2120 |
-
var values = [];
|
2121 |
-
self.eachBars(function(bar){
|
2122 |
-
values.push(bar.value);
|
2123 |
-
});
|
2124 |
-
return values;
|
2125 |
-
};
|
2126 |
-
|
2127 |
-
var scaleOptions = {
|
2128 |
-
templateString : this.options.scaleLabel,
|
2129 |
-
height : this.chart.height,
|
2130 |
-
width : this.chart.width,
|
2131 |
-
ctx : this.chart.ctx,
|
2132 |
-
textColor : this.options.scaleFontColor,
|
2133 |
-
fontSize : this.options.scaleFontSize,
|
2134 |
-
fontStyle : this.options.scaleFontStyle,
|
2135 |
-
fontFamily : this.options.scaleFontFamily,
|
2136 |
-
valuesCount : labels.length,
|
2137 |
-
beginAtZero : this.options.scaleBeginAtZero,
|
2138 |
-
integersOnly : this.options.scaleIntegersOnly,
|
2139 |
-
calculateYRange: function(currentHeight){
|
2140 |
-
var updatedRanges = helpers.calculateScaleRange(
|
2141 |
-
dataTotal(),
|
2142 |
-
currentHeight,
|
2143 |
-
this.fontSize,
|
2144 |
-
this.beginAtZero,
|
2145 |
-
this.integersOnly
|
2146 |
-
);
|
2147 |
-
helpers.extend(this, updatedRanges);
|
2148 |
-
},
|
2149 |
-
xLabels : labels,
|
2150 |
-
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
2151 |
-
lineWidth : this.options.scaleLineWidth,
|
2152 |
-
lineColor : this.options.scaleLineColor,
|
2153 |
-
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
2154 |
-
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
2155 |
-
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
|
2156 |
-
showLabels : this.options.scaleShowLabels,
|
2157 |
-
display : this.options.showScale
|
2158 |
-
};
|
2159 |
-
|
2160 |
-
if (this.options.scaleOverride){
|
2161 |
-
helpers.extend(scaleOptions, {
|
2162 |
-
calculateYRange: helpers.noop,
|
2163 |
-
steps: this.options.scaleSteps,
|
2164 |
-
stepValue: this.options.scaleStepWidth,
|
2165 |
-
min: this.options.scaleStartValue,
|
2166 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
2167 |
-
});
|
2168 |
-
}
|
2169 |
-
|
2170 |
-
this.scale = new this.ScaleClass(scaleOptions);
|
2171 |
-
},
|
2172 |
-
addData : function(valuesArray,label){
|
2173 |
-
//Map the values array for each of the datasets
|
2174 |
-
helpers.each(valuesArray,function(value,datasetIndex){
|
2175 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
2176 |
-
this.datasets[datasetIndex].bars.push(new this.BarClass({
|
2177 |
-
value : value,
|
2178 |
-
label : label,
|
2179 |
-
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
|
2180 |
-
y: this.scale.endPoint,
|
2181 |
-
width : this.scale.calculateBarWidth(this.datasets.length),
|
2182 |
-
base : this.scale.endPoint,
|
2183 |
-
strokeColor : this.datasets[datasetIndex].strokeColor,
|
2184 |
-
fillColor : this.datasets[datasetIndex].fillColor
|
2185 |
-
}));
|
2186 |
-
},this);
|
2187 |
-
|
2188 |
-
this.scale.addXLabel(label);
|
2189 |
-
//Then re-render the chart.
|
2190 |
-
this.update();
|
2191 |
-
},
|
2192 |
-
removeData : function(){
|
2193 |
-
this.scale.removeXLabel();
|
2194 |
-
//Then re-render the chart.
|
2195 |
-
helpers.each(this.datasets,function(dataset){
|
2196 |
-
dataset.bars.shift();
|
2197 |
-
},this);
|
2198 |
-
this.update();
|
2199 |
-
},
|
2200 |
-
reflow : function(){
|
2201 |
-
helpers.extend(this.BarClass.prototype,{
|
2202 |
-
y: this.scale.endPoint,
|
2203 |
-
base : this.scale.endPoint
|
2204 |
-
});
|
2205 |
-
var newScaleProps = helpers.extend({
|
2206 |
-
height : this.chart.height,
|
2207 |
-
width : this.chart.width
|
2208 |
-
});
|
2209 |
-
this.scale.update(newScaleProps);
|
2210 |
-
},
|
2211 |
-
draw : function(ease){
|
2212 |
-
var easingDecimal = ease || 1;
|
2213 |
-
this.clear();
|
2214 |
-
|
2215 |
-
var ctx = this.chart.ctx;
|
2216 |
-
|
2217 |
-
this.scale.draw(easingDecimal);
|
2218 |
-
|
2219 |
-
//Draw all the bars for each dataset
|
2220 |
-
helpers.each(this.datasets,function(dataset,datasetIndex){
|
2221 |
-
helpers.each(dataset.bars,function(bar,index){
|
2222 |
-
if (bar.hasValue()){
|
2223 |
-
bar.base = this.scale.endPoint;
|
2224 |
-
//Transition then draw
|
2225 |
-
bar.transition({
|
2226 |
-
x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
|
2227 |
-
y : this.scale.calculateY(bar.value),
|
2228 |
-
width : this.scale.calculateBarWidth(this.datasets.length)
|
2229 |
-
}, easingDecimal).draw();
|
2230 |
-
}
|
2231 |
-
},this);
|
2232 |
-
|
2233 |
-
},this);
|
2234 |
-
}
|
2235 |
-
});
|
2236 |
-
|
2237 |
-
|
2238 |
-
}).call(this);
|
2239 |
-
(function(){
|
2240 |
-
"use strict";
|
2241 |
-
|
2242 |
-
var root = this,
|
2243 |
-
Chart = root.Chart,
|
2244 |
-
//Cache a local reference to Chart.helpers
|
2245 |
-
helpers = Chart.helpers;
|
2246 |
-
|
2247 |
-
var defaultConfig = {
|
2248 |
-
//Boolean - Whether we should show a stroke on each segment
|
2249 |
-
segmentShowStroke : true,
|
2250 |
-
|
2251 |
-
//String - The colour of each segment stroke
|
2252 |
-
segmentStrokeColor : "#fff",
|
2253 |
-
|
2254 |
-
//Number - The width of each segment stroke
|
2255 |
-
segmentStrokeWidth : 2,
|
2256 |
-
|
2257 |
-
//The percentage of the chart that we cut out of the middle.
|
2258 |
-
percentageInnerCutout : 50,
|
2259 |
-
|
2260 |
-
//Number - Amount of animation steps
|
2261 |
-
animationSteps : 100,
|
2262 |
-
|
2263 |
-
//String - Animation easing effect
|
2264 |
-
animationEasing : "easeOutBounce",
|
2265 |
-
|
2266 |
-
//Boolean - Whether we animate the rotation of the Doughnut
|
2267 |
-
animateRotate : true,
|
2268 |
-
|
2269 |
-
//Boolean - Whether we animate scaling the Doughnut from the centre
|
2270 |
-
animateScale : false,
|
2271 |
-
|
2272 |
-
//String - A legend template
|
2273 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
|
2274 |
-
|
2275 |
-
};
|
2276 |
-
|
2277 |
-
|
2278 |
-
Chart.Type.extend({
|
2279 |
-
//Passing in a name registers this chart in the Chart namespace
|
2280 |
-
name: "Doughnut",
|
2281 |
-
//Providing a defaults will also register the deafults in the chart namespace
|
2282 |
-
defaults : defaultConfig,
|
2283 |
-
//Initialize is fired when the chart is initialized - Data is passed in as a parameter
|
2284 |
-
//Config is automatically merged by the core of Chart.js, and is available at this.options
|
2285 |
-
initialize: function(data){
|
2286 |
-
|
2287 |
-
//Declare segments as a static property to prevent inheriting across the Chart type prototype
|
2288 |
-
this.segments = [];
|
2289 |
-
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
|
2290 |
-
|
2291 |
-
this.SegmentArc = Chart.Arc.extend({
|
2292 |
-
ctx : this.chart.ctx,
|
2293 |
-
x : this.chart.width/2,
|
2294 |
-
y : this.chart.height/2
|
2295 |
-
});
|
2296 |
-
|
2297 |
-
//Set up tooltip events on the chart
|
2298 |
-
if (this.options.showTooltips){
|
2299 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
2300 |
-
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
|
2301 |
-
|
2302 |
-
helpers.each(this.segments,function(segment){
|
2303 |
-
segment.restore(["fillColor"]);
|
2304 |
-
});
|
2305 |
-
helpers.each(activeSegments,function(activeSegment){
|
2306 |
-
activeSegment.fillColor = activeSegment.highlightColor;
|
2307 |
-
});
|
2308 |
-
this.showTooltip(activeSegments);
|
2309 |
-
});
|
2310 |
-
}
|
2311 |
-
this.calculateTotal(data);
|
2312 |
-
|
2313 |
-
helpers.each(data,function(datapoint, index){
|
2314 |
-
this.addData(datapoint, index, true);
|
2315 |
-
},this);
|
2316 |
-
|
2317 |
-
this.render();
|
2318 |
-
},
|
2319 |
-
getSegmentsAtEvent : function(e){
|
2320 |
-
var segmentsArray = [];
|
2321 |
-
|
2322 |
-
var location = helpers.getRelativePosition(e);
|
2323 |
-
|
2324 |
-
helpers.each(this.segments,function(segment){
|
2325 |
-
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
|
2326 |
-
},this);
|
2327 |
-
return segmentsArray;
|
2328 |
-
},
|
2329 |
-
addData : function(segment, atIndex, silent){
|
2330 |
-
var index = atIndex || this.segments.length;
|
2331 |
-
this.segments.splice(index, 0, new this.SegmentArc({
|
2332 |
-
value : segment.value,
|
2333 |
-
outerRadius : (this.options.animateScale) ? 0 : this.outerRadius,
|
2334 |
-
innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,
|
2335 |
-
fillColor : segment.color,
|
2336 |
-
highlightColor : segment.highlight || segment.color,
|
2337 |
-
showStroke : this.options.segmentShowStroke,
|
2338 |
-
strokeWidth : this.options.segmentStrokeWidth,
|
2339 |
-
strokeColor : this.options.segmentStrokeColor,
|
2340 |
-
startAngle : Math.PI * 1.5,
|
2341 |
-
circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),
|
2342 |
-
label : segment.label
|
2343 |
-
}));
|
2344 |
-
if (!silent){
|
2345 |
-
this.reflow();
|
2346 |
-
this.update();
|
2347 |
-
}
|
2348 |
-
},
|
2349 |
-
calculateCircumference : function(value){
|
2350 |
-
return (Math.PI*2)*(value / this.total);
|
2351 |
-
},
|
2352 |
-
calculateTotal : function(data){
|
2353 |
-
this.total = 0;
|
2354 |
-
helpers.each(data,function(segment){
|
2355 |
-
this.total += segment.value;
|
2356 |
-
},this);
|
2357 |
-
},
|
2358 |
-
update : function(){
|
2359 |
-
this.calculateTotal(this.segments);
|
2360 |
-
|
2361 |
-
// Reset any highlight colours before updating.
|
2362 |
-
helpers.each(this.activeElements, function(activeElement){
|
2363 |
-
activeElement.restore(['fillColor']);
|
2364 |
-
});
|
2365 |
-
|
2366 |
-
helpers.each(this.segments,function(segment){
|
2367 |
-
segment.save();
|
2368 |
-
});
|
2369 |
-
this.render();
|
2370 |
-
},
|
2371 |
-
|
2372 |
-
removeData: function(atIndex){
|
2373 |
-
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
|
2374 |
-
this.segments.splice(indexToDelete, 1);
|
2375 |
-
this.reflow();
|
2376 |
-
this.update();
|
2377 |
-
},
|
2378 |
-
|
2379 |
-
reflow : function(){
|
2380 |
-
helpers.extend(this.SegmentArc.prototype,{
|
2381 |
-
x : this.chart.width/2,
|
2382 |
-
y : this.chart.height/2
|
2383 |
-
});
|
2384 |
-
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
|
2385 |
-
helpers.each(this.segments, function(segment){
|
2386 |
-
segment.update({
|
2387 |
-
outerRadius : this.outerRadius,
|
2388 |
-
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
|
2389 |
-
});
|
2390 |
-
}, this);
|
2391 |
-
},
|
2392 |
-
draw : function(easeDecimal){
|
2393 |
-
var animDecimal = (easeDecimal) ? easeDecimal : 1;
|
2394 |
-
this.clear();
|
2395 |
-
helpers.each(this.segments,function(segment,index){
|
2396 |
-
segment.transition({
|
2397 |
-
circumference : this.calculateCircumference(segment.value),
|
2398 |
-
outerRadius : this.outerRadius,
|
2399 |
-
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
|
2400 |
-
},animDecimal);
|
2401 |
-
|
2402 |
-
segment.endAngle = segment.startAngle + segment.circumference;
|
2403 |
-
|
2404 |
-
segment.draw();
|
2405 |
-
if (index === 0){
|
2406 |
-
segment.startAngle = Math.PI * 1.5;
|
2407 |
-
}
|
2408 |
-
//Check to see if it's the last segment, if not get the next and update the start angle
|
2409 |
-
if (index < this.segments.length-1){
|
2410 |
-
this.segments[index+1].startAngle = segment.endAngle;
|
2411 |
-
}
|
2412 |
-
},this);
|
2413 |
-
|
2414 |
-
}
|
2415 |
-
});
|
2416 |
-
|
2417 |
-
Chart.types.Doughnut.extend({
|
2418 |
-
name : "Pie",
|
2419 |
-
defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})
|
2420 |
-
});
|
2421 |
-
|
2422 |
-
}).call(this);
|
2423 |
-
(function(){
|
2424 |
-
"use strict";
|
2425 |
-
|
2426 |
-
var root = this,
|
2427 |
-
Chart = root.Chart,
|
2428 |
-
helpers = Chart.helpers;
|
2429 |
-
|
2430 |
-
var defaultConfig = {
|
2431 |
-
|
2432 |
-
///Boolean - Whether grid lines are shown across the chart
|
2433 |
-
scaleShowGridLines : true,
|
2434 |
-
|
2435 |
-
//String - Colour of the grid lines
|
2436 |
-
scaleGridLineColor : "rgba(0,0,0,.05)",
|
2437 |
-
|
2438 |
-
//Number - Width of the grid lines
|
2439 |
-
scaleGridLineWidth : 1,
|
2440 |
-
|
2441 |
-
//Boolean - Whether the line is curved between points
|
2442 |
-
bezierCurve : true,
|
2443 |
-
|
2444 |
-
//Number - Tension of the bezier curve between points
|
2445 |
-
bezierCurveTension : 0.4,
|
2446 |
-
|
2447 |
-
//Boolean - Whether to show a dot for each point
|
2448 |
-
pointDot : true,
|
2449 |
-
|
2450 |
-
//Number - Radius of each point dot in pixels
|
2451 |
-
pointDotRadius : 4,
|
2452 |
-
|
2453 |
-
//Number - Pixel width of point dot stroke
|
2454 |
-
pointDotStrokeWidth : 1,
|
2455 |
-
|
2456 |
-
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
2457 |
-
pointHitDetectionRadius : 20,
|
2458 |
-
|
2459 |
-
//Boolean - Whether to show a stroke for datasets
|
2460 |
-
datasetStroke : true,
|
2461 |
-
|
2462 |
-
//Number - Pixel width of dataset stroke
|
2463 |
-
datasetStrokeWidth : 2,
|
2464 |
-
|
2465 |
-
//Boolean - Whether to fill the dataset with a colour
|
2466 |
-
datasetFill : true,
|
2467 |
-
|
2468 |
-
//String - A legend template
|
2469 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
2470 |
-
|
2471 |
-
};
|
2472 |
-
|
2473 |
-
|
2474 |
-
Chart.Type.extend({
|
2475 |
-
name: "Line",
|
2476 |
-
defaults : defaultConfig,
|
2477 |
-
initialize: function(data){
|
2478 |
-
//Declare the extension of the default point, to cater for the options passed in to the constructor
|
2479 |
-
this.PointClass = Chart.Point.extend({
|
2480 |
-
strokeWidth : this.options.pointDotStrokeWidth,
|
2481 |
-
radius : this.options.pointDotRadius,
|
2482 |
-
display: this.options.pointDot,
|
2483 |
-
hitDetectionRadius : this.options.pointHitDetectionRadius,
|
2484 |
-
ctx : this.chart.ctx,
|
2485 |
-
inRange : function(mouseX){
|
2486 |
-
return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));
|
2487 |
-
}
|
2488 |
-
});
|
2489 |
-
|
2490 |
-
this.datasets = [];
|
2491 |
-
|
2492 |
-
//Set up tooltip events on the chart
|
2493 |
-
if (this.options.showTooltips){
|
2494 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
2495 |
-
var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
|
2496 |
-
this.eachPoints(function(point){
|
2497 |
-
point.restore(['fillColor', 'strokeColor']);
|
2498 |
-
});
|
2499 |
-
helpers.each(activePoints, function(activePoint){
|
2500 |
-
activePoint.fillColor = activePoint.highlightFill;
|
2501 |
-
activePoint.strokeColor = activePoint.highlightStroke;
|
2502 |
-
});
|
2503 |
-
this.showTooltip(activePoints);
|
2504 |
-
});
|
2505 |
-
}
|
2506 |
-
|
2507 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
2508 |
-
helpers.each(data.datasets,function(dataset){
|
2509 |
-
|
2510 |
-
var datasetObject = {
|
2511 |
-
label : dataset.label || null,
|
2512 |
-
fillColor : dataset.fillColor,
|
2513 |
-
strokeColor : dataset.strokeColor,
|
2514 |
-
pointColor : dataset.pointColor,
|
2515 |
-
pointStrokeColor : dataset.pointStrokeColor,
|
2516 |
-
points : []
|
2517 |
-
};
|
2518 |
-
|
2519 |
-
this.datasets.push(datasetObject);
|
2520 |
-
|
2521 |
-
|
2522 |
-
helpers.each(dataset.data,function(dataPoint,index){
|
2523 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
2524 |
-
datasetObject.points.push(new this.PointClass({
|
2525 |
-
value : dataPoint,
|
2526 |
-
label : data.labels[index],
|
2527 |
-
datasetLabel: dataset.label,
|
2528 |
-
strokeColor : dataset.pointStrokeColor,
|
2529 |
-
fillColor : dataset.pointColor,
|
2530 |
-
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
2531 |
-
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
2532 |
-
}));
|
2533 |
-
},this);
|
2534 |
-
|
2535 |
-
this.buildScale(data.labels);
|
2536 |
-
|
2537 |
-
|
2538 |
-
this.eachPoints(function(point, index){
|
2539 |
-
helpers.extend(point, {
|
2540 |
-
x: this.scale.calculateX(index),
|
2541 |
-
y: this.scale.endPoint
|
2542 |
-
});
|
2543 |
-
point.save();
|
2544 |
-
}, this);
|
2545 |
-
|
2546 |
-
},this);
|
2547 |
-
|
2548 |
-
|
2549 |
-
this.render();
|
2550 |
-
},
|
2551 |
-
update : function(){
|
2552 |
-
this.scale.update();
|
2553 |
-
// Reset any highlight colours before updating.
|
2554 |
-
helpers.each(this.activeElements, function(activeElement){
|
2555 |
-
activeElement.restore(['fillColor', 'strokeColor']);
|
2556 |
-
});
|
2557 |
-
this.eachPoints(function(point){
|
2558 |
-
point.save();
|
2559 |
-
});
|
2560 |
-
this.render();
|
2561 |
-
},
|
2562 |
-
eachPoints : function(callback){
|
2563 |
-
helpers.each(this.datasets,function(dataset){
|
2564 |
-
helpers.each(dataset.points,callback,this);
|
2565 |
-
},this);
|
2566 |
-
},
|
2567 |
-
getPointsAtEvent : function(e){
|
2568 |
-
var pointsArray = [],
|
2569 |
-
eventPosition = helpers.getRelativePosition(e);
|
2570 |
-
helpers.each(this.datasets,function(dataset){
|
2571 |
-
helpers.each(dataset.points,function(point){
|
2572 |
-
if (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);
|
2573 |
-
});
|
2574 |
-
},this);
|
2575 |
-
return pointsArray;
|
2576 |
-
},
|
2577 |
-
buildScale : function(labels){
|
2578 |
-
var self = this;
|
2579 |
-
|
2580 |
-
var dataTotal = function(){
|
2581 |
-
var values = [];
|
2582 |
-
self.eachPoints(function(point){
|
2583 |
-
values.push(point.value);
|
2584 |
-
});
|
2585 |
-
|
2586 |
-
return values;
|
2587 |
-
};
|
2588 |
-
|
2589 |
-
var scaleOptions = {
|
2590 |
-
templateString : this.options.scaleLabel,
|
2591 |
-
height : this.chart.height,
|
2592 |
-
width : this.chart.width,
|
2593 |
-
ctx : this.chart.ctx,
|
2594 |
-
textColor : this.options.scaleFontColor,
|
2595 |
-
fontSize : this.options.scaleFontSize,
|
2596 |
-
fontStyle : this.options.scaleFontStyle,
|
2597 |
-
fontFamily : this.options.scaleFontFamily,
|
2598 |
-
valuesCount : labels.length,
|
2599 |
-
beginAtZero : this.options.scaleBeginAtZero,
|
2600 |
-
integersOnly : this.options.scaleIntegersOnly,
|
2601 |
-
calculateYRange : function(currentHeight){
|
2602 |
-
var updatedRanges = helpers.calculateScaleRange(
|
2603 |
-
dataTotal(),
|
2604 |
-
currentHeight,
|
2605 |
-
this.fontSize,
|
2606 |
-
this.beginAtZero,
|
2607 |
-
this.integersOnly
|
2608 |
-
);
|
2609 |
-
helpers.extend(this, updatedRanges);
|
2610 |
-
},
|
2611 |
-
xLabels : labels,
|
2612 |
-
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
2613 |
-
lineWidth : this.options.scaleLineWidth,
|
2614 |
-
lineColor : this.options.scaleLineColor,
|
2615 |
-
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
2616 |
-
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
2617 |
-
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
|
2618 |
-
showLabels : this.options.scaleShowLabels,
|
2619 |
-
display : this.options.showScale
|
2620 |
-
};
|
2621 |
-
|
2622 |
-
if (this.options.scaleOverride){
|
2623 |
-
helpers.extend(scaleOptions, {
|
2624 |
-
calculateYRange: helpers.noop,
|
2625 |
-
steps: this.options.scaleSteps,
|
2626 |
-
stepValue: this.options.scaleStepWidth,
|
2627 |
-
min: this.options.scaleStartValue,
|
2628 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
2629 |
-
});
|
2630 |
-
}
|
2631 |
-
|
2632 |
-
|
2633 |
-
this.scale = new Chart.Scale(scaleOptions);
|
2634 |
-
},
|
2635 |
-
addData : function(valuesArray,label){
|
2636 |
-
//Map the values array for each of the datasets
|
2637 |
-
|
2638 |
-
helpers.each(valuesArray,function(value,datasetIndex){
|
2639 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
2640 |
-
this.datasets[datasetIndex].points.push(new this.PointClass({
|
2641 |
-
value : value,
|
2642 |
-
label : label,
|
2643 |
-
x: this.scale.calculateX(this.scale.valuesCount+1),
|
2644 |
-
y: this.scale.endPoint,
|
2645 |
-
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
|
2646 |
-
fillColor : this.datasets[datasetIndex].pointColor
|
2647 |
-
}));
|
2648 |
-
},this);
|
2649 |
-
|
2650 |
-
this.scale.addXLabel(label);
|
2651 |
-
//Then re-render the chart.
|
2652 |
-
this.update();
|
2653 |
-
},
|
2654 |
-
removeData : function(){
|
2655 |
-
this.scale.removeXLabel();
|
2656 |
-
//Then re-render the chart.
|
2657 |
-
helpers.each(this.datasets,function(dataset){
|
2658 |
-
dataset.points.shift();
|
2659 |
-
},this);
|
2660 |
-
this.update();
|
2661 |
-
},
|
2662 |
-
reflow : function(){
|
2663 |
-
var newScaleProps = helpers.extend({
|
2664 |
-
height : this.chart.height,
|
2665 |
-
width : this.chart.width
|
2666 |
-
});
|
2667 |
-
this.scale.update(newScaleProps);
|
2668 |
-
},
|
2669 |
-
draw : function(ease){
|
2670 |
-
var easingDecimal = ease || 1;
|
2671 |
-
this.clear();
|
2672 |
-
|
2673 |
-
var ctx = this.chart.ctx;
|
2674 |
-
|
2675 |
-
// Some helper methods for getting the next/prev points
|
2676 |
-
var hasValue = function(item){
|
2677 |
-
return item.value !== null;
|
2678 |
-
},
|
2679 |
-
nextPoint = function(point, collection, index){
|
2680 |
-
return helpers.findNextWhere(collection, hasValue, index) || point;
|
2681 |
-
},
|
2682 |
-
previousPoint = function(point, collection, index){
|
2683 |
-
return helpers.findPreviousWhere(collection, hasValue, index) || point;
|
2684 |
-
};
|
2685 |
-
|
2686 |
-
this.scale.draw(easingDecimal);
|
2687 |
-
|
2688 |
-
|
2689 |
-
helpers.each(this.datasets,function(dataset){
|
2690 |
-
var pointsWithValues = helpers.where(dataset.points, hasValue);
|
2691 |
-
|
2692 |
-
//Transition each point first so that the line and point drawing isn't out of sync
|
2693 |
-
//We can use this extra loop to calculate the control points of this dataset also in this loop
|
2694 |
-
|
2695 |
-
helpers.each(dataset.points, function(point, index){
|
2696 |
-
if (point.hasValue()){
|
2697 |
-
point.transition({
|
2698 |
-
y : this.scale.calculateY(point.value),
|
2699 |
-
x : this.scale.calculateX(index)
|
2700 |
-
}, easingDecimal);
|
2701 |
-
}
|
2702 |
-
},this);
|
2703 |
-
|
2704 |
-
|
2705 |
-
// Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point
|
2706 |
-
// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed
|
2707 |
-
if (this.options.bezierCurve){
|
2708 |
-
helpers.each(pointsWithValues, function(point, index){
|
2709 |
-
var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;
|
2710 |
-
point.controlPoints = helpers.splineCurve(
|
2711 |
-
previousPoint(point, pointsWithValues, index),
|
2712 |
-
point,
|
2713 |
-
nextPoint(point, pointsWithValues, index),
|
2714 |
-
tension
|
2715 |
-
);
|
2716 |
-
|
2717 |
-
// Prevent the bezier going outside of the bounds of the graph
|
2718 |
-
|
2719 |
-
// Cap puter bezier handles to the upper/lower scale bounds
|
2720 |
-
if (point.controlPoints.outer.y > this.scale.endPoint){
|
2721 |
-
point.controlPoints.outer.y = this.scale.endPoint;
|
2722 |
-
}
|
2723 |
-
else if (point.controlPoints.outer.y < this.scale.startPoint){
|
2724 |
-
point.controlPoints.outer.y = this.scale.startPoint;
|
2725 |
-
}
|
2726 |
-
|
2727 |
-
// Cap inner bezier handles to the upper/lower scale bounds
|
2728 |
-
if (point.controlPoints.inner.y > this.scale.endPoint){
|
2729 |
-
point.controlPoints.inner.y = this.scale.endPoint;
|
2730 |
-
}
|
2731 |
-
else if (point.controlPoints.inner.y < this.scale.startPoint){
|
2732 |
-
point.controlPoints.inner.y = this.scale.startPoint;
|
2733 |
-
}
|
2734 |
-
},this);
|
2735 |
-
}
|
2736 |
-
|
2737 |
-
|
2738 |
-
//Draw the line between all the points
|
2739 |
-
ctx.lineWidth = this.options.datasetStrokeWidth;
|
2740 |
-
ctx.strokeStyle = dataset.strokeColor;
|
2741 |
-
ctx.beginPath();
|
2742 |
-
|
2743 |
-
helpers.each(pointsWithValues, function(point, index){
|
2744 |
-
if (index === 0){
|
2745 |
-
ctx.moveTo(point.x, point.y);
|
2746 |
-
}
|
2747 |
-
else{
|
2748 |
-
if(this.options.bezierCurve){
|
2749 |
-
var previous = previousPoint(point, pointsWithValues, index);
|
2750 |
-
|
2751 |
-
ctx.bezierCurveTo(
|
2752 |
-
previous.controlPoints.outer.x,
|
2753 |
-
previous.controlPoints.outer.y,
|
2754 |
-
point.controlPoints.inner.x,
|
2755 |
-
point.controlPoints.inner.y,
|
2756 |
-
point.x,
|
2757 |
-
point.y
|
2758 |
-
);
|
2759 |
-
}
|
2760 |
-
else{
|
2761 |
-
ctx.lineTo(point.x,point.y);
|
2762 |
-
}
|
2763 |
-
}
|
2764 |
-
}, this);
|
2765 |
-
|
2766 |
-
ctx.stroke();
|
2767 |
-
|
2768 |
-
if (this.options.datasetFill && pointsWithValues.length > 0){
|
2769 |
-
//Round off the line by going to the base of the chart, back to the start, then fill.
|
2770 |
-
ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);
|
2771 |
-
ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);
|
2772 |
-
ctx.fillStyle = dataset.fillColor;
|
2773 |
-
ctx.closePath();
|
2774 |
-
ctx.fill();
|
2775 |
-
}
|
2776 |
-
|
2777 |
-
//Now draw the points over the line
|
2778 |
-
//A little inefficient double looping, but better than the line
|
2779 |
-
//lagging behind the point positions
|
2780 |
-
helpers.each(pointsWithValues,function(point){
|
2781 |
-
point.draw();
|
2782 |
-
});
|
2783 |
-
},this);
|
2784 |
-
}
|
2785 |
-
});
|
2786 |
-
|
2787 |
-
|
2788 |
-
}).call(this);
|
2789 |
-
(function(){
|
2790 |
-
"use strict";
|
2791 |
-
|
2792 |
-
var root = this,
|
2793 |
-
Chart = root.Chart,
|
2794 |
-
//Cache a local reference to Chart.helpers
|
2795 |
-
helpers = Chart.helpers;
|
2796 |
-
|
2797 |
-
var defaultConfig = {
|
2798 |
-
//Boolean - Show a backdrop to the scale label
|
2799 |
-
scaleShowLabelBackdrop : true,
|
2800 |
-
|
2801 |
-
//String - The colour of the label backdrop
|
2802 |
-
scaleBackdropColor : "rgba(255,255,255,0.75)",
|
2803 |
-
|
2804 |
-
// Boolean - Whether the scale should begin at zero
|
2805 |
-
scaleBeginAtZero : true,
|
2806 |
-
|
2807 |
-
//Number - The backdrop padding above & below the label in pixels
|
2808 |
-
scaleBackdropPaddingY : 2,
|
2809 |
-
|
2810 |
-
//Number - The backdrop padding to the side of the label in pixels
|
2811 |
-
scaleBackdropPaddingX : 2,
|
2812 |
-
|
2813 |
-
//Boolean - Show line for each value in the scale
|
2814 |
-
scaleShowLine : true,
|
2815 |
-
|
2816 |
-
//Boolean - Stroke a line around each segment in the chart
|
2817 |
-
segmentShowStroke : true,
|
2818 |
-
|
2819 |
-
//String - The colour of the stroke on each segement.
|
2820 |
-
segmentStrokeColor : "#fff",
|
2821 |
-
|
2822 |
-
//Number - The width of the stroke value in pixels
|
2823 |
-
segmentStrokeWidth : 2,
|
2824 |
-
|
2825 |
-
//Number - Amount of animation steps
|
2826 |
-
animationSteps : 100,
|
2827 |
-
|
2828 |
-
//String - Animation easing effect.
|
2829 |
-
animationEasing : "easeOutBounce",
|
2830 |
-
|
2831 |
-
//Boolean - Whether to animate the rotation of the chart
|
2832 |
-
animateRotate : true,
|
2833 |
-
|
2834 |
-
//Boolean - Whether to animate scaling the chart from the centre
|
2835 |
-
animateScale : false,
|
2836 |
-
|
2837 |
-
//String - A legend template
|
2838 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
|
2839 |
-
};
|
2840 |
-
|
2841 |
-
|
2842 |
-
Chart.Type.extend({
|
2843 |
-
//Passing in a name registers this chart in the Chart namespace
|
2844 |
-
name: "PolarArea",
|
2845 |
-
//Providing a defaults will also register the deafults in the chart namespace
|
2846 |
-
defaults : defaultConfig,
|
2847 |
-
//Initialize is fired when the chart is initialized - Data is passed in as a parameter
|
2848 |
-
//Config is automatically merged by the core of Chart.js, and is available at this.options
|
2849 |
-
initialize: function(data){
|
2850 |
-
this.segments = [];
|
2851 |
-
//Declare segment class as a chart instance specific class, so it can share props for this instance
|
2852 |
-
this.SegmentArc = Chart.Arc.extend({
|
2853 |
-
showStroke : this.options.segmentShowStroke,
|
2854 |
-
strokeWidth : this.options.segmentStrokeWidth,
|
2855 |
-
strokeColor : this.options.segmentStrokeColor,
|
2856 |
-
ctx : this.chart.ctx,
|
2857 |
-
innerRadius : 0,
|
2858 |
-
x : this.chart.width/2,
|
2859 |
-
y : this.chart.height/2
|
2860 |
-
});
|
2861 |
-
this.scale = new Chart.RadialScale({
|
2862 |
-
display: this.options.showScale,
|
2863 |
-
fontStyle: this.options.scaleFontStyle,
|
2864 |
-
fontSize: this.options.scaleFontSize,
|
2865 |
-
fontFamily: this.options.scaleFontFamily,
|
2866 |
-
fontColor: this.options.scaleFontColor,
|
2867 |
-
showLabels: this.options.scaleShowLabels,
|
2868 |
-
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
|
2869 |
-
backdropColor: this.options.scaleBackdropColor,
|
2870 |
-
backdropPaddingY : this.options.scaleBackdropPaddingY,
|
2871 |
-
backdropPaddingX: this.options.scaleBackdropPaddingX,
|
2872 |
-
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
|
2873 |
-
lineColor: this.options.scaleLineColor,
|
2874 |
-
lineArc: true,
|
2875 |
-
width: this.chart.width,
|
2876 |
-
height: this.chart.height,
|
2877 |
-
xCenter: this.chart.width/2,
|
2878 |
-
yCenter: this.chart.height/2,
|
2879 |
-
ctx : this.chart.ctx,
|
2880 |
-
templateString: this.options.scaleLabel,
|
2881 |
-
valuesCount: data.length
|
2882 |
-
});
|
2883 |
-
|
2884 |
-
this.updateScaleRange(data);
|
2885 |
-
|
2886 |
-
this.scale.update();
|
2887 |
-
|
2888 |
-
helpers.each(data,function(segment,index){
|
2889 |
-
this.addData(segment,index,true);
|
2890 |
-
},this);
|
2891 |
-
|
2892 |
-
//Set up tooltip events on the chart
|
2893 |
-
if (this.options.showTooltips){
|
2894 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
2895 |
-
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
|
2896 |
-
helpers.each(this.segments,function(segment){
|
2897 |
-
segment.restore(["fillColor"]);
|
2898 |
-
});
|
2899 |
-
helpers.each(activeSegments,function(activeSegment){
|
2900 |
-
activeSegment.fillColor = activeSegment.highlightColor;
|
2901 |
-
});
|
2902 |
-
this.showTooltip(activeSegments);
|
2903 |
-
});
|
2904 |
-
}
|
2905 |
-
|
2906 |
-
this.render();
|
2907 |
-
},
|
2908 |
-
getSegmentsAtEvent : function(e){
|
2909 |
-
var segmentsArray = [];
|
2910 |
-
|
2911 |
-
var location = helpers.getRelativePosition(e);
|
2912 |
-
|
2913 |
-
helpers.each(this.segments,function(segment){
|
2914 |
-
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
|
2915 |
-
},this);
|
2916 |
-
return segmentsArray;
|
2917 |
-
},
|
2918 |
-
addData : function(segment, atIndex, silent){
|
2919 |
-
var index = atIndex || this.segments.length;
|
2920 |
-
|
2921 |
-
this.segments.splice(index, 0, new this.SegmentArc({
|
2922 |
-
fillColor: segment.color,
|
2923 |
-
highlightColor: segment.highlight || segment.color,
|
2924 |
-
label: segment.label,
|
2925 |
-
value: segment.value,
|
2926 |
-
outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
|
2927 |
-
circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
|
2928 |
-
startAngle: Math.PI * 1.5
|
2929 |
-
}));
|
2930 |
-
if (!silent){
|
2931 |
-
this.reflow();
|
2932 |
-
this.update();
|
2933 |
-
}
|
2934 |
-
},
|
2935 |
-
removeData: function(atIndex){
|
2936 |
-
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
|
2937 |
-
this.segments.splice(indexToDelete, 1);
|
2938 |
-
this.reflow();
|
2939 |
-
this.update();
|
2940 |
-
},
|
2941 |
-
calculateTotal: function(data){
|
2942 |
-
this.total = 0;
|
2943 |
-
helpers.each(data,function(segment){
|
2944 |
-
this.total += segment.value;
|
2945 |
-
},this);
|
2946 |
-
this.scale.valuesCount = this.segments.length;
|
2947 |
-
},
|
2948 |
-
updateScaleRange: function(datapoints){
|
2949 |
-
var valuesArray = [];
|
2950 |
-
helpers.each(datapoints,function(segment){
|
2951 |
-
valuesArray.push(segment.value);
|
2952 |
-
});
|
2953 |
-
|
2954 |
-
var scaleSizes = (this.options.scaleOverride) ?
|
2955 |
-
{
|
2956 |
-
steps: this.options.scaleSteps,
|
2957 |
-
stepValue: this.options.scaleStepWidth,
|
2958 |
-
min: this.options.scaleStartValue,
|
2959 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
2960 |
-
} :
|
2961 |
-
helpers.calculateScaleRange(
|
2962 |
-
valuesArray,
|
2963 |
-
helpers.min([this.chart.width, this.chart.height])/2,
|
2964 |
-
this.options.scaleFontSize,
|
2965 |
-
this.options.scaleBeginAtZero,
|
2966 |
-
this.options.scaleIntegersOnly
|
2967 |
-
);
|
2968 |
-
|
2969 |
-
helpers.extend(
|
2970 |
-
this.scale,
|
2971 |
-
scaleSizes,
|
2972 |
-
{
|
2973 |
-
size: helpers.min([this.chart.width, this.chart.height]),
|
2974 |
-
xCenter: this.chart.width/2,
|
2975 |
-
yCenter: this.chart.height/2
|
2976 |
-
}
|
2977 |
-
);
|
2978 |
-
|
2979 |
-
},
|
2980 |
-
update : function(){
|
2981 |
-
this.calculateTotal(this.segments);
|
2982 |
-
|
2983 |
-
helpers.each(this.segments,function(segment){
|
2984 |
-
segment.save();
|
2985 |
-
});
|
2986 |
-
this.render();
|
2987 |
-
},
|
2988 |
-
reflow : function(){
|
2989 |
-
helpers.extend(this.SegmentArc.prototype,{
|
2990 |
-
x : this.chart.width/2,
|
2991 |
-
y : this.chart.height/2
|
2992 |
-
});
|
2993 |
-
this.updateScaleRange(this.segments);
|
2994 |
-
this.scale.update();
|
2995 |
-
|
2996 |
-
helpers.extend(this.scale,{
|
2997 |
-
xCenter: this.chart.width/2,
|
2998 |
-
yCenter: this.chart.height/2
|
2999 |
-
});
|
3000 |
-
|
3001 |
-
helpers.each(this.segments, function(segment){
|
3002 |
-
segment.update({
|
3003 |
-
outerRadius : this.scale.calculateCenterOffset(segment.value)
|
3004 |
-
});
|
3005 |
-
}, this);
|
3006 |
-
|
3007 |
-
},
|
3008 |
-
draw : function(ease){
|
3009 |
-
var easingDecimal = ease || 1;
|
3010 |
-
//Clear & draw the canvas
|
3011 |
-
this.clear();
|
3012 |
-
helpers.each(this.segments,function(segment, index){
|
3013 |
-
segment.transition({
|
3014 |
-
circumference : this.scale.getCircumference(),
|
3015 |
-
outerRadius : this.scale.calculateCenterOffset(segment.value)
|
3016 |
-
},easingDecimal);
|
3017 |
-
|
3018 |
-
segment.endAngle = segment.startAngle + segment.circumference;
|
3019 |
-
|
3020 |
-
// If we've removed the first segment we need to set the first one to
|
3021 |
-
// start at the top.
|
3022 |
-
if (index === 0){
|
3023 |
-
segment.startAngle = Math.PI * 1.5;
|
3024 |
-
}
|
3025 |
-
|
3026 |
-
//Check to see if it's the last segment, if not get the next and update the start angle
|
3027 |
-
if (index < this.segments.length - 1){
|
3028 |
-
this.segments[index+1].startAngle = segment.endAngle;
|
3029 |
-
}
|
3030 |
-
segment.draw();
|
3031 |
-
}, this);
|
3032 |
-
this.scale.draw();
|
3033 |
-
}
|
3034 |
-
});
|
3035 |
-
|
3036 |
-
}).call(this);
|
3037 |
-
(function(){
|
3038 |
-
"use strict";
|
3039 |
-
|
3040 |
-
var root = this,
|
3041 |
-
Chart = root.Chart,
|
3042 |
-
helpers = Chart.helpers;
|
3043 |
-
|
3044 |
-
|
3045 |
-
|
3046 |
-
Chart.Type.extend({
|
3047 |
-
name: "Radar",
|
3048 |
-
defaults:{
|
3049 |
-
//Boolean - Whether to show lines for each scale point
|
3050 |
-
scaleShowLine : true,
|
3051 |
-
|
3052 |
-
//Boolean - Whether we show the angle lines out of the radar
|
3053 |
-
angleShowLineOut : true,
|
3054 |
-
|
3055 |
-
//Boolean - Whether to show labels on the scale
|
3056 |
-
scaleShowLabels : false,
|
3057 |
-
|
3058 |
-
// Boolean - Whether the scale should begin at zero
|
3059 |
-
scaleBeginAtZero : true,
|
3060 |
-
|
3061 |
-
//String - Colour of the angle line
|
3062 |
-
angleLineColor : "rgba(0,0,0,.1)",
|
3063 |
-
|
3064 |
-
//Number - Pixel width of the angle line
|
3065 |
-
angleLineWidth : 1,
|
3066 |
-
|
3067 |
-
//String - Point label font declaration
|
3068 |
-
pointLabelFontFamily : "'Arial'",
|
3069 |
-
|
3070 |
-
//String - Point label font weight
|
3071 |
-
pointLabelFontStyle : "normal",
|
3072 |
-
|
3073 |
-
//Number - Point label font size in pixels
|
3074 |
-
pointLabelFontSize : 10,
|
3075 |
-
|
3076 |
-
//String - Point label font colour
|
3077 |
-
pointLabelFontColor : "#666",
|
3078 |
-
|
3079 |
-
//Boolean - Whether to show a dot for each point
|
3080 |
-
pointDot : true,
|
3081 |
-
|
3082 |
-
//Number - Radius of each point dot in pixels
|
3083 |
-
pointDotRadius : 3,
|
3084 |
-
|
3085 |
-
//Number - Pixel width of point dot stroke
|
3086 |
-
pointDotStrokeWidth : 1,
|
3087 |
-
|
3088 |
-
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
3089 |
-
pointHitDetectionRadius : 20,
|
3090 |
-
|
3091 |
-
//Boolean - Whether to show a stroke for datasets
|
3092 |
-
datasetStroke : true,
|
3093 |
-
|
3094 |
-
//Number - Pixel width of dataset stroke
|
3095 |
-
datasetStrokeWidth : 2,
|
3096 |
-
|
3097 |
-
//Boolean - Whether to fill the dataset with a colour
|
3098 |
-
datasetFill : true,
|
3099 |
-
|
3100 |
-
//String - A legend template
|
3101 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
3102 |
-
|
3103 |
-
},
|
3104 |
-
|
3105 |
-
initialize: function(data){
|
3106 |
-
this.PointClass = Chart.Point.extend({
|
3107 |
-
strokeWidth : this.options.pointDotStrokeWidth,
|
3108 |
-
radius : this.options.pointDotRadius,
|
3109 |
-
display: this.options.pointDot,
|
3110 |
-
hitDetectionRadius : this.options.pointHitDetectionRadius,
|
3111 |
-
ctx : this.chart.ctx
|
3112 |
-
});
|
3113 |
-
|
3114 |
-
this.datasets = [];
|
3115 |
-
|
3116 |
-
this.buildScale(data);
|
3117 |
-
|
3118 |
-
//Set up tooltip events on the chart
|
3119 |
-
if (this.options.showTooltips){
|
3120 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
3121 |
-
var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
|
3122 |
-
|
3123 |
-
this.eachPoints(function(point){
|
3124 |
-
point.restore(['fillColor', 'strokeColor']);
|
3125 |
-
});
|
3126 |
-
helpers.each(activePointsCollection, function(activePoint){
|
3127 |
-
activePoint.fillColor = activePoint.highlightFill;
|
3128 |
-
activePoint.strokeColor = activePoint.highlightStroke;
|
3129 |
-
});
|
3130 |
-
|
3131 |
-
this.showTooltip(activePointsCollection);
|
3132 |
-
});
|
3133 |
-
}
|
3134 |
-
|
3135 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
3136 |
-
helpers.each(data.datasets,function(dataset){
|
3137 |
-
|
3138 |
-
var datasetObject = {
|
3139 |
-
label: dataset.label || null,
|
3140 |
-
fillColor : dataset.fillColor,
|
3141 |
-
strokeColor : dataset.strokeColor,
|
3142 |
-
pointColor : dataset.pointColor,
|
3143 |
-
pointStrokeColor : dataset.pointStrokeColor,
|
3144 |
-
points : []
|
3145 |
-
};
|
3146 |
-
|
3147 |
-
this.datasets.push(datasetObject);
|
3148 |
-
|
3149 |
-
helpers.each(dataset.data,function(dataPoint,index){
|
3150 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
3151 |
-
var pointPosition;
|
3152 |
-
if (!this.scale.animation){
|
3153 |
-
pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));
|
3154 |
-
}
|
3155 |
-
datasetObject.points.push(new this.PointClass({
|
3156 |
-
value : dataPoint,
|
3157 |
-
label : data.labels[index],
|
3158 |
-
datasetLabel: dataset.label,
|
3159 |
-
x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
|
3160 |
-
y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
|
3161 |
-
strokeColor : dataset.pointStrokeColor,
|
3162 |
-
fillColor : dataset.pointColor,
|
3163 |
-
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
3164 |
-
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
3165 |
-
}));
|
3166 |
-
},this);
|
3167 |
-
|
3168 |
-
},this);
|
3169 |
-
|
3170 |
-
this.render();
|
3171 |
-
},
|
3172 |
-
eachPoints : function(callback){
|
3173 |
-
helpers.each(this.datasets,function(dataset){
|
3174 |
-
helpers.each(dataset.points,callback,this);
|
3175 |
-
},this);
|
3176 |
-
},
|
3177 |
-
|
3178 |
-
getPointsAtEvent : function(evt){
|
3179 |
-
var mousePosition = helpers.getRelativePosition(evt),
|
3180 |
-
fromCenter = helpers.getAngleFromPoint({
|
3181 |
-
x: this.scale.xCenter,
|
3182 |
-
y: this.scale.yCenter
|
3183 |
-
}, mousePosition);
|
3184 |
-
|
3185 |
-
var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,
|
3186 |
-
pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),
|
3187 |
-
activePointsCollection = [];
|
3188 |
-
|
3189 |
-
// If we're at the top, make the pointIndex 0 to get the first of the array.
|
3190 |
-
if (pointIndex >= this.scale.valuesCount || pointIndex < 0){
|
3191 |
-
pointIndex = 0;
|
3192 |
-
}
|
3193 |
-
|
3194 |
-
if (fromCenter.distance <= this.scale.drawingArea){
|
3195 |
-
helpers.each(this.datasets, function(dataset){
|
3196 |
-
activePointsCollection.push(dataset.points[pointIndex]);
|
3197 |
-
});
|
3198 |
-
}
|
3199 |
-
|
3200 |
-
return activePointsCollection;
|
3201 |
-
},
|
3202 |
-
|
3203 |
-
buildScale : function(data){
|
3204 |
-
this.scale = new Chart.RadialScale({
|
3205 |
-
display: this.options.showScale,
|
3206 |
-
fontStyle: this.options.scaleFontStyle,
|
3207 |
-
fontSize: this.options.scaleFontSize,
|
3208 |
-
fontFamily: this.options.scaleFontFamily,
|
3209 |
-
fontColor: this.options.scaleFontColor,
|
3210 |
-
showLabels: this.options.scaleShowLabels,
|
3211 |
-
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
|
3212 |
-
backdropColor: this.options.scaleBackdropColor,
|
3213 |
-
backdropPaddingY : this.options.scaleBackdropPaddingY,
|
3214 |
-
backdropPaddingX: this.options.scaleBackdropPaddingX,
|
3215 |
-
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
|
3216 |
-
lineColor: this.options.scaleLineColor,
|
3217 |
-
angleLineColor : this.options.angleLineColor,
|
3218 |
-
angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,
|
3219 |
-
// Point labels at the edge of each line
|
3220 |
-
pointLabelFontColor : this.options.pointLabelFontColor,
|
3221 |
-
pointLabelFontSize : this.options.pointLabelFontSize,
|
3222 |
-
pointLabelFontFamily : this.options.pointLabelFontFamily,
|
3223 |
-
pointLabelFontStyle : this.options.pointLabelFontStyle,
|
3224 |
-
height : this.chart.height,
|
3225 |
-
width: this.chart.width,
|
3226 |
-
xCenter: this.chart.width/2,
|
3227 |
-
yCenter: this.chart.height/2,
|
3228 |
-
ctx : this.chart.ctx,
|
3229 |
-
templateString: this.options.scaleLabel,
|
3230 |
-
labels: data.labels,
|
3231 |
-
valuesCount: data.datasets[0].data.length
|
3232 |
-
});
|
3233 |
-
|
3234 |
-
this.scale.setScaleSize();
|
3235 |
-
this.updateScaleRange(data.datasets);
|
3236 |
-
this.scale.buildYLabels();
|
3237 |
-
},
|
3238 |
-
updateScaleRange: function(datasets){
|
3239 |
-
var valuesArray = (function(){
|
3240 |
-
var totalDataArray = [];
|
3241 |
-
helpers.each(datasets,function(dataset){
|
3242 |
-
if (dataset.data){
|
3243 |
-
totalDataArray = totalDataArray.concat(dataset.data);
|
3244 |
-
}
|
3245 |
-
else {
|
3246 |
-
helpers.each(dataset.points, function(point){
|
3247 |
-
totalDataArray.push(point.value);
|
3248 |
-
});
|
3249 |
-
}
|
3250 |
-
});
|
3251 |
-
return totalDataArray;
|
3252 |
-
})();
|
3253 |
-
|
3254 |
-
|
3255 |
-
var scaleSizes = (this.options.scaleOverride) ?
|
3256 |
-
{
|
3257 |
-
steps: this.options.scaleSteps,
|
3258 |
-
stepValue: this.options.scaleStepWidth,
|
3259 |
-
min: this.options.scaleStartValue,
|
3260 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
3261 |
-
} :
|
3262 |
-
helpers.calculateScaleRange(
|
3263 |
-
valuesArray,
|
3264 |
-
helpers.min([this.chart.width, this.chart.height])/2,
|
3265 |
-
this.options.scaleFontSize,
|
3266 |
-
this.options.scaleBeginAtZero,
|
3267 |
-
this.options.scaleIntegersOnly
|
3268 |
-
);
|
3269 |
-
|
3270 |
-
helpers.extend(
|
3271 |
-
this.scale,
|
3272 |
-
scaleSizes
|
3273 |
-
);
|
3274 |
-
|
3275 |
-
},
|
3276 |
-
addData : function(valuesArray,label){
|
3277 |
-
//Map the values array for each of the datasets
|
3278 |
-
this.scale.valuesCount++;
|
3279 |
-
helpers.each(valuesArray,function(value,datasetIndex){
|
3280 |
-
var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));
|
3281 |
-
this.datasets[datasetIndex].points.push(new this.PointClass({
|
3282 |
-
value : value,
|
3283 |
-
label : label,
|
3284 |
-
x: pointPosition.x,
|
3285 |
-
y: pointPosition.y,
|
3286 |
-
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
|
3287 |
-
fillColor : this.datasets[datasetIndex].pointColor
|
3288 |
-
}));
|
3289 |
-
},this);
|
3290 |
-
|
3291 |
-
this.scale.labels.push(label);
|
3292 |
-
|
3293 |
-
this.reflow();
|
3294 |
-
|
3295 |
-
this.update();
|
3296 |
-
},
|
3297 |
-
removeData : function(){
|
3298 |
-
this.scale.valuesCount--;
|
3299 |
-
this.scale.labels.shift();
|
3300 |
-
helpers.each(this.datasets,function(dataset){
|
3301 |
-
dataset.points.shift();
|
3302 |
-
},this);
|
3303 |
-
this.reflow();
|
3304 |
-
this.update();
|
3305 |
-
},
|
3306 |
-
update : function(){
|
3307 |
-
this.eachPoints(function(point){
|
3308 |
-
point.save();
|
3309 |
-
});
|
3310 |
-
this.reflow();
|
3311 |
-
this.render();
|
3312 |
-
},
|
3313 |
-
reflow: function(){
|
3314 |
-
helpers.extend(this.scale, {
|
3315 |
-
width : this.chart.width,
|
3316 |
-
height: this.chart.height,
|
3317 |
-
size : helpers.min([this.chart.width, this.chart.height]),
|
3318 |
-
xCenter: this.chart.width/2,
|
3319 |
-
yCenter: this.chart.height/2
|
3320 |
-
});
|
3321 |
-
this.updateScaleRange(this.datasets);
|
3322 |
-
this.scale.setScaleSize();
|
3323 |
-
this.scale.buildYLabels();
|
3324 |
-
},
|
3325 |
-
draw : function(ease){
|
3326 |
-
var easeDecimal = ease || 1,
|
3327 |
-
ctx = this.chart.ctx;
|
3328 |
-
this.clear();
|
3329 |
-
this.scale.draw();
|
3330 |
-
|
3331 |
-
helpers.each(this.datasets,function(dataset){
|
3332 |
-
|
3333 |
-
//Transition each point first so that the line and point drawing isn't out of sync
|
3334 |
-
helpers.each(dataset.points,function(point,index){
|
3335 |
-
if (point.hasValue()){
|
3336 |
-
point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
|
3337 |
-
}
|
3338 |
-
},this);
|
3339 |
-
|
3340 |
-
|
3341 |
-
|
3342 |
-
//Draw the line between all the points
|
3343 |
-
ctx.lineWidth = this.options.datasetStrokeWidth;
|
3344 |
-
ctx.strokeStyle = dataset.strokeColor;
|
3345 |
-
ctx.beginPath();
|
3346 |
-
helpers.each(dataset.points,function(point,index){
|
3347 |
-
if (index === 0){
|
3348 |
-
ctx.moveTo(point.x,point.y);
|
3349 |
-
}
|
3350 |
-
else{
|
3351 |
-
ctx.lineTo(point.x,point.y);
|
3352 |
-
}
|
3353 |
-
},this);
|
3354 |
-
ctx.closePath();
|
3355 |
-
ctx.stroke();
|
3356 |
-
|
3357 |
-
ctx.fillStyle = dataset.fillColor;
|
3358 |
-
ctx.fill();
|
3359 |
-
|
3360 |
-
//Now draw the points over the line
|
3361 |
-
//A little inefficient double looping, but better than the line
|
3362 |
-
//lagging behind the point positions
|
3363 |
-
helpers.each(dataset.points,function(point){
|
3364 |
-
if (point.hasValue()){
|
3365 |
-
point.draw();
|
3366 |
-
}
|
3367 |
-
});
|
3368 |
-
|
3369 |
-
},this);
|
3370 |
-
|
3371 |
-
}
|
3372 |
-
|
3373 |
-
});
|
3374 |
-
|
3375 |
-
|
3376 |
-
|
3377 |
-
|
3378 |
-
|
3379 |
-
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/Chart.min.js
CHANGED
@@ -1,11 +1,7 @@
|
|
1 |
/*!
|
2 |
-
* Chart.js
|
3 |
-
*
|
4 |
-
*
|
5 |
-
*
|
6 |
-
* Copyright 2014 Nick Downie
|
7 |
-
* Released under the MIT license
|
8 |
-
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
|
9 |
*/
|
10 |
-
(function(){"use strict";var t=this,i=t.Chart,e=function(t){this.canvas=t.canvas,this.ctx=t;this.width=t.canvas.width,this.height=t.canvas.height;return this.aspectRatio=this.width/this.height,s.retinaScale(this),this};e.defaults={global:{animation:!0,animationSteps:60,animationEasing:"easeOutQuart",showScale:!0,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleIntegersOnly:!0,scaleBeginAtZero:!1,scaleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",responsive:!1,maintainAspectRatio:!0,showTooltips:!0,tooltipEvents:["mousemove","touchstart","touchmove","mouseout"],tooltipFillColor:"rgba(0,0,0,0.8)",tooltipFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipFontSize:14,tooltipFontStyle:"normal",tooltipFontColor:"#fff",tooltipTitleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipTitleFontSize:14,tooltipTitleFontStyle:"bold",tooltipTitleFontColor:"#fff",tooltipYPadding:6,tooltipXPadding:6,tooltipCaretSize:8,tooltipCornerRadius:6,tooltipXOffset:10,tooltipTemplate:"<%if (label){%><%=label%>: <%}%><%= value %>",multiTooltipTemplate:"<%= value %>",multiTooltipKeyBackground:"#fff",onAnimationProgress:function(){},onAnimationComplete:function(){}}},e.types={};var s=e.helpers={},n=s.each=function(t,i,e){var s=Array.prototype.slice.call(arguments,3);if(t)if(t.length===+t.length){var n;for(n=0;n<t.length;n++)i.apply(e,[t[n],n].concat(s))}else for(var o in t)i.apply(e,[t[o],o].concat(s))},o=s.clone=function(t){var i={};return n(t,function(e,s){t.hasOwnProperty(s)&&(i[s]=e)}),i},a=s.extend=function(t){return n(Array.prototype.slice.call(arguments,1),function(i){n(i,function(e,s){i.hasOwnProperty(s)&&(t[s]=e)})}),t},h=s.merge=function(){var t=Array.prototype.slice.call(arguments,0);return t.unshift({}),a.apply(null,t)},l=s.indexOf=function(t,i){if(Array.prototype.indexOf)return t.indexOf(i);for(var e=0;e<t.length;e++)if(t[e]===i)return e;return-1},r=(s.where=function(t,i){var e=[];return s.each(t,function(t){i(t)&&e.push(t)}),e},s.findNextWhere=function(t,i,e){e||(e=-1);for(var s=e+1;s<t.length;s++){var n=t[s];if(i(n))return n}},s.findPreviousWhere=function(t,i,e){e||(e=t.length);for(var s=e-1;s>=0;s--){var n=t[s];if(i(n))return n}},s.inherits=function(t){var i=this,e=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return i.apply(this,arguments)},s=function(){this.constructor=e};return s.prototype=i.prototype,e.prototype=new s,e.extend=r,t&&a(e.prototype,t),e.__super__=i.prototype,e}),c=s.noop=function(){},u=s.uid=function(){var t=0;return function(){return"chart-"+t++}}(),d=s.warn=function(t){window.console&&"function"==typeof window.console.warn&&console.warn(t)},p=s.amd="function"==typeof t.define&&t.define.amd,f=s.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},g=s.max=function(t){return Math.max.apply(Math,t)},m=s.min=function(t){return Math.min.apply(Math,t)},v=(s.cap=function(t,i,e){if(f(i)){if(t>i)return i}else if(f(e)&&e>t)return e;return t},s.getDecimalPlaces=function(t){return t%1!==0&&f(t)?t.toString().split(".")[1].length:0}),x=s.radians=function(t){return t*(Math.PI/180)},S=(s.getAngleFromPoint=function(t,i){var e=i.x-t.x,s=i.y-t.y,n=Math.sqrt(e*e+s*s),o=2*Math.PI+Math.atan2(s,e);return 0>e&&0>s&&(o+=2*Math.PI),{angle:o,distance:n}},s.aliasPixel=function(t){return t%2===0?0:.5}),y=(s.splineCurve=function(t,i,e,s){var n=Math.sqrt(Math.pow(i.x-t.x,2)+Math.pow(i.y-t.y,2)),o=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),a=s*n/(n+o),h=s*o/(n+o);return{inner:{x:i.x-a*(e.x-t.x),y:i.y-a*(e.y-t.y)},outer:{x:i.x+h*(e.x-t.x),y:i.y+h*(e.y-t.y)}}},s.calculateOrderOfMagnitude=function(t){return Math.floor(Math.log(t)/Math.LN10)}),C=(s.calculateScaleRange=function(t,i,e,s,n){var o=2,a=Math.floor(i/(1.5*e)),h=o>=a,l=g(t),r=m(t);l===r&&(l+=.5,r>=.5&&!s?r-=.5:l+=.5);for(var c=Math.abs(l-r),u=y(c),d=Math.ceil(l/(1*Math.pow(10,u)))*Math.pow(10,u),p=s?0:Math.floor(r/(1*Math.pow(10,u)))*Math.pow(10,u),f=d-p,v=Math.pow(10,u),x=Math.round(f/v);(x>a||a>2*x)&&!h;)if(x>a)v*=2,x=Math.round(f/v),x%1!==0&&(h=!0);else if(n&&u>=0){if(v/2%1!==0)break;v/=2,x=Math.round(f/v)}else v/=2,x=Math.round(f/v);return h&&(x=o,v=f/x),{steps:x,stepValue:v,min:p,max:p+x*v}},s.template=function(t,i){function e(t,i){var e=/\W/.test(t)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+t.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):s[t]=s[t];return i?e(i):e}if(t instanceof Function)return t(i);var s={};return e(t,i)}),b=(s.generateLabels=function(t,i,e,s){var o=new Array(i);return labelTemplateString&&n(o,function(i,n){o[n]=C(t,{value:e+s*(n+1)})}),o},s.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),-(s*Math.pow(2,10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e)))},easeOutElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),s*Math.pow(2,-10*t)*Math.sin(2*(1*t-i)*Math.PI/e)+1)},easeInOutElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:2==(t/=.5)?1:(e||(e=.3*1.5),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),1>t?-.5*s*Math.pow(2,10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e):s*Math.pow(2,-10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e)*.5+1)},easeInBack:function(t){var i=1.70158;return 1*(t/=1)*t*((i+1)*t-i)},easeOutBack:function(t){var i=1.70158;return 1*((t=t/1-1)*t*((i+1)*t+i)+1)},easeInOutBack:function(t){var i=1.70158;return(t/=.5)<1?.5*t*t*(((i*=1.525)+1)*t-i):.5*((t-=2)*t*(((i*=1.525)+1)*t+i)+2)},easeInBounce:function(t){return 1-b.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?7.5625*t*t:2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*b.easeInBounce(2*t):.5*b.easeOutBounce(2*t-1)+.5}}),w=s.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),P=(s.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),s.animationLoop=function(t,i,e,s,n,o){var a=0,h=b[e]||b.linear,l=function(){a++;var e=a/i,r=h(e);t.call(o,r,e,a),s.call(o,r,e),i>a?o.animationFrame=w(l):n.apply(o)};w(l)},s.getRelativePosition=function(t){var i,e,s=t.originalEvent||t,n=t.currentTarget||t.srcElement,o=n.getBoundingClientRect();return s.touches?(i=s.touches[0].clientX-o.left,e=s.touches[0].clientY-o.top):(i=s.clientX-o.left,e=s.clientY-o.top),{x:i,y:e}},s.addEvent=function(t,i,e){t.addEventListener?t.addEventListener(i,e):t.attachEvent?t.attachEvent("on"+i,e):t["on"+i]=e}),L=s.removeEvent=function(t,i,e){t.removeEventListener?t.removeEventListener(i,e,!1):t.detachEvent?t.detachEvent("on"+i,e):t["on"+i]=c},k=(s.bindEvents=function(t,i,e){t.events||(t.events={}),n(i,function(i){t.events[i]=function(){e.apply(t,arguments)},P(t.chart.canvas,i,t.events[i])})},s.unbindEvents=function(t,i){n(i,function(i,e){L(t.chart.canvas,e,i)})}),F=s.getMaximumWidth=function(t){var i=t.parentNode;return i.clientWidth},R=s.getMaximumHeight=function(t){var i=t.parentNode;return i.clientHeight},A=(s.getMaximumSize=s.getMaximumWidth,s.retinaScale=function(t){var i=t.ctx,e=t.canvas.width,s=t.canvas.height;window.devicePixelRatio&&(i.canvas.style.width=e+"px",i.canvas.style.height=s+"px",i.canvas.height=s*window.devicePixelRatio,i.canvas.width=e*window.devicePixelRatio,i.scale(window.devicePixelRatio,window.devicePixelRatio))}),T=s.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},M=s.fontString=function(t,i,e){return i+" "+t+"px "+e},W=s.longestText=function(t,i,e){t.font=i;var s=0;return n(e,function(i){var e=t.measureText(i).width;s=e>s?e:s}),s},z=s.drawRoundedRectangle=function(t,i,e,s,n,o){t.beginPath(),t.moveTo(i+o,e),t.lineTo(i+s-o,e),t.quadraticCurveTo(i+s,e,i+s,e+o),t.lineTo(i+s,e+n-o),t.quadraticCurveTo(i+s,e+n,i+s-o,e+n),t.lineTo(i+o,e+n),t.quadraticCurveTo(i,e+n,i,e+n-o),t.lineTo(i,e+o),t.quadraticCurveTo(i,e,i+o,e),t.closePath()};e.instances={},e.Type=function(t,i,s){this.options=i,this.chart=s,this.id=u(),e.instances[this.id]=this,i.responsive&&this.resize(),this.initialize.call(this,t)},a(e.Type.prototype,{initialize:function(){return this},clear:function(){return T(this.chart),this},stop:function(){return s.cancelAnimFrame.call(t,this.animationFrame),this},resize:function(t){this.stop();var i=this.chart.canvas,e=F(this.chart.canvas),s=this.options.maintainAspectRatio?e/this.chart.aspectRatio:R(this.chart.canvas);return i.width=this.chart.width=e,i.height=this.chart.height=s,A(this.chart),"function"==typeof t&&t.apply(this,Array.prototype.slice.call(arguments,1)),this},reflow:c,render:function(t){return t&&this.reflow(),this.options.animation&&!t?s.animationLoop(this.draw,this.options.animationSteps,this.options.animationEasing,this.options.onAnimationProgress,this.options.onAnimationComplete,this):(this.draw(),this.options.onAnimationComplete.call(this)),this},generateLegend:function(){return C(this.options.legendTemplate,this)},destroy:function(){this.clear(),k(this,this.events),delete e.instances[this.id]},showTooltip:function(t,i){"undefined"==typeof this.activeElements&&(this.activeElements=[]);var o=function(t){var i=!1;return t.length!==this.activeElements.length?i=!0:(n(t,function(t,e){t!==this.activeElements[e]&&(i=!0)},this),i)}.call(this,t);if(o||i){if(this.activeElements=t,this.draw(),t.length>0)if(this.datasets&&this.datasets.length>1){for(var a,h,r=this.datasets.length-1;r>=0&&(a=this.datasets[r].points||this.datasets[r].bars||this.datasets[r].segments,h=l(a,t[0]),-1===h);r--);var c=[],u=[],d=function(){var t,i,e,n,o,a=[],l=[],r=[];return s.each(this.datasets,function(i){t=i.points||i.bars||i.segments,t[h]&&t[h].hasValue()&&a.push(t[h])}),s.each(a,function(t){l.push(t.x),r.push(t.y),c.push(s.template(this.options.multiTooltipTemplate,t)),u.push({fill:t._saved.fillColor||t.fillColor,stroke:t._saved.strokeColor||t.strokeColor})},this),o=m(r),e=g(r),n=m(l),i=g(l),{x:n>this.chart.width/2?n:i,y:(o+e)/2}}.call(this,h);new e.MultiTooltip({x:d.x,y:d.y,xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,xOffset:this.options.tooltipXOffset,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,titleTextColor:this.options.tooltipTitleFontColor,titleFontFamily:this.options.tooltipTitleFontFamily,titleFontStyle:this.options.tooltipTitleFontStyle,titleFontSize:this.options.tooltipTitleFontSize,cornerRadius:this.options.tooltipCornerRadius,labels:c,legendColors:u,legendColorBackground:this.options.multiTooltipKeyBackground,title:t[0].label,chart:this.chart,ctx:this.chart.ctx}).draw()}else n(t,function(t){var i=t.tooltipPosition();new e.Tooltip({x:Math.round(i.x),y:Math.round(i.y),xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,caretHeight:this.options.tooltipCaretSize,cornerRadius:this.options.tooltipCornerRadius,text:C(this.options.tooltipTemplate,t),chart:this.chart}).draw()},this);return this}},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)}}),e.Type.extend=function(t){var i=this,s=function(){return i.apply(this,arguments)};if(s.prototype=o(i.prototype),a(s.prototype,t),s.extend=e.Type.extend,t.name||i.prototype.name){var n=t.name||i.prototype.name,l=e.defaults[i.prototype.name]?o(e.defaults[i.prototype.name]):{};e.defaults[n]=a(l,t.defaults),e.types[n]=s,e.prototype[n]=function(t,i){var o=h(e.defaults.global,e.defaults[n],i||{});return new s(t,o,this)}}else d("Name not provided for this chart, so it hasn't been registered");return i},e.Element=function(t){a(this,t),this.initialize.apply(this,arguments),this.save()},a(e.Element.prototype,{initialize:function(){},restore:function(t){return t?n(t,function(t){this[t]=this._saved[t]},this):a(this,this._saved),this},save:function(){return this._saved=o(this),delete this._saved._saved,this},update:function(t){return n(t,function(t,i){this._saved[i]=this[i],this[i]=t},this),this},transition:function(t,i){return n(t,function(t,e){this[e]=(t-this._saved[e])*i+this._saved[e]},this),this},tooltipPosition:function(){return{x:this.x,y:this.y}},hasValue:function(){return f(this.value)}}),e.Element.extend=r,e.Point=e.Element.extend({display:!0,inRange:function(t,i){var e=this.hitDetectionRadius+this.radius;return Math.pow(t-this.x,2)+Math.pow(i-this.y,2)<Math.pow(e,2)},draw:function(){if(this.display){var t=this.ctx;t.beginPath(),t.arc(this.x,this.y,this.radius,0,2*Math.PI),t.closePath(),t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.fillStyle=this.fillColor,t.fill(),t.stroke()}}}),e.Arc=e.Element.extend({inRange:function(t,i){var e=s.getAngleFromPoint(this,{x:t,y:i}),n=e.angle>=this.startAngle&&e.angle<=this.endAngle,o=e.distance>=this.innerRadius&&e.distance<=this.outerRadius;return n&&o},tooltipPosition:function(){var t=this.startAngle+(this.endAngle-this.startAngle)/2,i=(this.outerRadius-this.innerRadius)/2+this.innerRadius;return{x:this.x+Math.cos(t)*i,y:this.y+Math.sin(t)*i}},draw:function(t){var i=this.ctx;i.beginPath(),i.arc(this.x,this.y,this.outerRadius,this.startAngle,this.endAngle),i.arc(this.x,this.y,this.innerRadius,this.endAngle,this.startAngle,!0),i.closePath(),i.strokeStyle=this.strokeColor,i.lineWidth=this.strokeWidth,i.fillStyle=this.fillColor,i.fill(),i.lineJoin="bevel",this.showStroke&&i.stroke()}}),e.Rectangle=e.Element.extend({draw:function(){var t=this.ctx,i=this.width/2,e=this.x-i,s=this.x+i,n=this.base-(this.base-this.y),o=this.strokeWidth/2;this.showStroke&&(e+=o,s-=o,n+=o),t.beginPath(),t.fillStyle=this.fillColor,t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.moveTo(e,this.base),t.lineTo(e,n),t.lineTo(s,n),t.lineTo(s,this.base),t.fill(),this.showStroke&&t.stroke()},height:function(){return this.base-this.y},inRange:function(t,i){return t>=this.x-this.width/2&&t<=this.x+this.width/2&&i>=this.y&&i<=this.base}}),e.Tooltip=e.Element.extend({draw:function(){var t=this.chart.ctx;t.font=M(this.fontSize,this.fontStyle,this.fontFamily),this.xAlign="center",this.yAlign="above";var i=2,e=t.measureText(this.text).width+2*this.xPadding,s=this.fontSize+2*this.yPadding,n=s+this.caretHeight+i;this.x+e/2>this.chart.width?this.xAlign="left":this.x-e/2<0&&(this.xAlign="right"),this.y-n<0&&(this.yAlign="below");var o=this.x-e/2,a=this.y-n;switch(t.fillStyle=this.fillColor,this.yAlign){case"above":t.beginPath(),t.moveTo(this.x,this.y-i),t.lineTo(this.x+this.caretHeight,this.y-(i+this.caretHeight)),t.lineTo(this.x-this.caretHeight,this.y-(i+this.caretHeight)),t.closePath(),t.fill();break;case"below":a=this.y+i+this.caretHeight,t.beginPath(),t.moveTo(this.x,this.y+i),t.lineTo(this.x+this.caretHeight,this.y+i+this.caretHeight),t.lineTo(this.x-this.caretHeight,this.y+i+this.caretHeight),t.closePath(),t.fill()}switch(this.xAlign){case"left":o=this.x-e+(this.cornerRadius+this.caretHeight);break;case"right":o=this.x-(this.cornerRadius+this.caretHeight)}z(t,o,a,e,s,this.cornerRadius),t.fill(),t.fillStyle=this.textColor,t.textAlign="center",t.textBaseline="middle",t.fillText(this.text,o+e/2,a+s/2)}}),e.MultiTooltip=e.Element.extend({initialize:function(){this.font=M(this.fontSize,this.fontStyle,this.fontFamily),this.titleFont=M(this.titleFontSize,this.titleFontStyle,this.titleFontFamily),this.height=this.labels.length*this.fontSize+(this.labels.length-1)*(this.fontSize/2)+2*this.yPadding+1.5*this.titleFontSize,this.ctx.font=this.titleFont;var t=this.ctx.measureText(this.title).width,i=W(this.ctx,this.font,this.labels)+this.fontSize+3,e=g([i,t]);this.width=e+2*this.xPadding;var s=this.height/2;this.y-s<0?this.y=s:this.y+s>this.chart.height&&(this.y=this.chart.height-s),this.x>this.chart.width/2?this.x-=this.xOffset+this.width:this.x+=this.xOffset},getLineHeight:function(t){var i=this.y-this.height/2+this.yPadding,e=t-1;return 0===t?i+this.titleFontSize/2:i+(1.5*this.fontSize*e+this.fontSize/2)+1.5*this.titleFontSize},draw:function(){z(this.ctx,this.x,this.y-this.height/2,this.width,this.height,this.cornerRadius);var t=this.ctx;t.fillStyle=this.fillColor,t.fill(),t.closePath(),t.textAlign="left",t.textBaseline="middle",t.fillStyle=this.titleTextColor,t.font=this.titleFont,t.fillText(this.title,this.x+this.xPadding,this.getLineHeight(0)),t.font=this.font,s.each(this.labels,function(i,e){t.fillStyle=this.textColor,t.fillText(i,this.x+this.xPadding+this.fontSize+3,this.getLineHeight(e+1)),t.fillStyle=this.legendColorBackground,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize),t.fillStyle=this.legendColors[e].fill,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize)},this)}}),e.Scale=e.Element.extend({initialize:function(){this.fit()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}));this.yLabelWidth=this.display&&this.showLabels?W(this.ctx,this.font,this.yLabels):0},addXLabel:function(t){this.xLabels.push(t),this.valuesCount++,this.fit()},removeXLabel:function(){this.xLabels.shift(),this.valuesCount--,this.fit()},fit:function(){this.startPoint=this.display?this.fontSize:0,this.endPoint=this.display?this.height-1.5*this.fontSize-5:this.height,this.startPoint+=this.padding,this.endPoint-=this.padding;var t,i=this.endPoint-this.startPoint;for(this.calculateYRange(i),this.buildYLabels(),this.calculateXLabelRotation();i>this.endPoint-this.startPoint;)i=this.endPoint-this.startPoint,t=this.yLabelWidth,this.calculateYRange(i),this.buildYLabels(),t<this.yLabelWidth&&this.calculateXLabelRotation()},calculateXLabelRotation:function(){this.ctx.font=this.font;var t,i,e=this.ctx.measureText(this.xLabels[0]).width,s=this.ctx.measureText(this.xLabels[this.xLabels.length-1]).width;if(this.xScalePaddingRight=s/2+3,this.xScalePaddingLeft=e/2>this.yLabelWidth+10?e/2:this.yLabelWidth+10,this.xLabelRotation=0,this.display){var n,o=W(this.ctx,this.font,this.xLabels);this.xLabelWidth=o;for(var a=Math.floor(this.calculateX(1)-this.calculateX(0))-6;this.xLabelWidth>a&&0===this.xLabelRotation||this.xLabelWidth>a&&this.xLabelRotation<=90&&this.xLabelRotation>0;)n=Math.cos(x(this.xLabelRotation)),t=n*e,i=n*s,t+this.fontSize/2>this.yLabelWidth+8&&(this.xScalePaddingLeft=t+this.fontSize/2),this.xScalePaddingRight=this.fontSize/2,this.xLabelRotation++,this.xLabelWidth=n*o;this.xLabelRotation>0&&(this.endPoint-=Math.sin(x(this.xLabelRotation))*o+3)}else this.xLabelWidth=0,this.xScalePaddingRight=this.padding,this.xScalePaddingLeft=this.padding},calculateYRange:c,drawingArea:function(){return this.startPoint-this.endPoint},calculateY:function(t){var i=this.drawingArea()/(this.min-this.max);return this.endPoint-i*(t-this.min)},calculateX:function(t){var i=(this.xLabelRotation>0,this.width-(this.xScalePaddingLeft+this.xScalePaddingRight)),e=i/(this.valuesCount-(this.offsetGridLines?0:1)),s=e*t+this.xScalePaddingLeft;return this.offsetGridLines&&(s+=e/2),Math.round(s)},update:function(t){s.extend(this,t),this.fit()},draw:function(){var t=this.ctx,i=(this.endPoint-this.startPoint)/this.steps,e=Math.round(this.xScalePaddingLeft);this.display&&(t.fillStyle=this.textColor,t.font=this.font,n(this.yLabels,function(n,o){var a=this.endPoint-i*o,h=Math.round(a);t.textAlign="right",t.textBaseline="middle",this.showLabels&&t.fillText(n,e-10,a),t.beginPath(),o>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),h+=s.aliasPixel(t.lineWidth),t.moveTo(e,h),t.lineTo(this.width,h),t.stroke(),t.closePath(),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(e-5,h),t.lineTo(e,h),t.stroke(),t.closePath()},this),n(this.xLabels,function(i,e){var s=this.calculateX(e)+S(this.lineWidth),n=this.calculateX(e-(this.offsetGridLines?.5:0))+S(this.lineWidth),o=this.xLabelRotation>0;t.beginPath(),e>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),t.moveTo(n,this.endPoint),t.lineTo(n,this.startPoint-3),t.stroke(),t.closePath(),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(n,this.endPoint),t.lineTo(n,this.endPoint+5),t.stroke(),t.closePath(),t.save(),t.translate(s,o?this.endPoint+12:this.endPoint+8),t.rotate(-1*x(this.xLabelRotation)),t.font=this.font,t.textAlign=o?"right":"center",t.textBaseline=o?"middle":"top",t.fillText(i,0,0),t.restore()},this))}}),e.RadialScale=e.Element.extend({initialize:function(){this.size=m([this.height,this.width]),this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2},calculateCenterOffset:function(t){var i=this.drawingArea/(this.max-this.min);return(t-this.min)*i},update:function(){this.lineArc?this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2:this.setScaleSize(),this.buildYLabels()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}))},getCircumference:function(){return 2*Math.PI/this.valuesCount},setScaleSize:function(){var t,i,e,s,n,o,a,h,l,r,c,u,d=m([this.height/2-this.pointLabelFontSize-5,this.width/2]),p=this.width,g=0;for(this.ctx.font=M(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),i=0;i<this.valuesCount;i++)t=this.getPointPosition(i,d),e=this.ctx.measureText(C(this.templateString,{value:this.labels[i]})).width+5,0===i||i===this.valuesCount/2?(s=e/2,t.x+s>p&&(p=t.x+s,n=i),t.x-s<g&&(g=t.x-s,a=i)):i<this.valuesCount/2?t.x+e>p&&(p=t.x+e,n=i):i>this.valuesCount/2&&t.x-e<g&&(g=t.x-e,a=i);l=g,r=Math.ceil(p-this.width),o=this.getIndexAngle(n),h=this.getIndexAngle(a),c=r/Math.sin(o+Math.PI/2),u=l/Math.sin(h+Math.PI/2),c=f(c)?c:0,u=f(u)?u:0,this.drawingArea=d-(u+c)/2,this.setCenterPoint(u,c)},setCenterPoint:function(t,i){var e=this.width-i-this.drawingArea,s=t+this.drawingArea;this.xCenter=(s+e)/2,this.yCenter=this.height/2},getIndexAngle:function(t){var i=2*Math.PI/this.valuesCount;return t*i-Math.PI/2},getPointPosition:function(t,i){var e=this.getIndexAngle(t);return{x:Math.cos(e)*i+this.xCenter,y:Math.sin(e)*i+this.yCenter}},draw:function(){if(this.display){var t=this.ctx;if(n(this.yLabels,function(i,e){if(e>0){var s,n=e*(this.drawingArea/this.steps),o=this.yCenter-n;if(this.lineWidth>0)if(t.strokeStyle=this.lineColor,t.lineWidth=this.lineWidth,this.lineArc)t.beginPath(),t.arc(this.xCenter,this.yCenter,n,0,2*Math.PI),t.closePath(),t.stroke();else{t.beginPath();for(var a=0;a<this.valuesCount;a++)s=this.getPointPosition(a,this.calculateCenterOffset(this.min+e*this.stepValue)),0===a?t.moveTo(s.x,s.y):t.lineTo(s.x,s.y);t.closePath(),t.stroke()}if(this.showLabels){if(t.font=M(this.fontSize,this.fontStyle,this.fontFamily),this.showLabelBackdrop){var h=t.measureText(i).width;t.fillStyle=this.backdropColor,t.fillRect(this.xCenter-h/2-this.backdropPaddingX,o-this.fontSize/2-this.backdropPaddingY,h+2*this.backdropPaddingX,this.fontSize+2*this.backdropPaddingY)}t.textAlign="center",t.textBaseline="middle",t.fillStyle=this.fontColor,t.fillText(i,this.xCenter,o)}}},this),!this.lineArc){t.lineWidth=this.angleLineWidth,t.strokeStyle=this.angleLineColor;for(var i=this.valuesCount-1;i>=0;i--){if(this.angleLineWidth>0){var e=this.getPointPosition(i,this.calculateCenterOffset(this.max));t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(e.x,e.y),t.stroke(),t.closePath()}var s=this.getPointPosition(i,this.calculateCenterOffset(this.max)+5);t.font=M(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),t.fillStyle=this.pointLabelFontColor;var o=this.labels.length,a=this.labels.length/2,h=a/2,l=h>i||i>o-h,r=i===h||i===o-h;t.textAlign=0===i?"center":i===a?"center":a>i?"left":"right",t.textBaseline=r?"middle":l?"bottom":"top",t.fillText(this.labels[i],s.x,s.y)}}}}}),s.addEvent(window,"resize",function(){var t;return function(){clearTimeout(t),t=setTimeout(function(){n(e.instances,function(t){t.options.responsive&&t.resize(t.render,!0)})},50)}}()),p?define(function(){return e}):"object"==typeof module&&module.exports&&(module.exports=e),t.Chart=e,e.noConflict=function(){return t.Chart=i,e}}).call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleBeginAtZero:!0,scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].fillColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"Bar",defaults:s,initialize:function(t){var s=this.options;this.ScaleClass=i.Scale.extend({offsetGridLines:!0,calculateBarX:function(t,i,e){var n=this.calculateBaseWidth(),o=this.calculateX(e)-n/2,a=this.calculateBarWidth(t);return o+a*i+i*s.barDatasetSpacing+a/2},calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)-2*s.barValueSpacing},calculateBarWidth:function(t){var i=this.calculateBaseWidth()-(t-1)*s.barDatasetSpacing;return i/t}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getBarsAtEvent(t):[];this.eachBars(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),this.BarClass=i.Rectangle.extend({strokeWidth:this.options.barStrokeWidth,showStroke:this.options.barShowStroke,ctx:this.chart.ctx}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,bars:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.bars.push(new this.BarClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.strokeColor,fillColor:i.fillColor,highlightFill:i.highlightFill||i.fillColor,highlightStroke:i.highlightStroke||i.strokeColor}))},this)},this),this.buildScale(t.labels),this.BarClass.prototype.base=this.scale.endPoint,this.eachBars(function(t,i,s){e.extend(t,{width:this.scale.calculateBarWidth(this.datasets.length),x:this.scale.calculateBarX(this.datasets.length,s,i),y:this.scale.endPoint}),t.save()},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachBars(function(t){t.save()}),this.render()},eachBars:function(t){e.each(this.datasets,function(i,s){e.each(i.bars,t,this,s)},this)},getBarsAtEvent:function(t){for(var i,s=[],n=e.getRelativePosition(t),o=function(t){s.push(t.bars[i])},a=0;a<this.datasets.length;a++)for(i=0;i<this.datasets[a].bars.length;i++)if(this.datasets[a].bars[i].inRange(n.x,n.y))return e.each(this.datasets,o),s;return s},buildScale:function(t){var i=this,s=function(){var t=[];return i.eachBars(function(i){t.push(i.value)}),t},n={templateString:this.options.scaleLabel,height:this.chart.height,width:this.chart.width,ctx:this.chart.ctx,textColor:this.options.scaleFontColor,fontSize:this.options.scaleFontSize,fontStyle:this.options.scaleFontStyle,fontFamily:this.options.scaleFontFamily,valuesCount:t.length,beginAtZero:this.options.scaleBeginAtZero,integersOnly:this.options.scaleIntegersOnly,calculateYRange:function(t){var i=e.calculateScaleRange(s(),t,this.fontSize,this.beginAtZero,this.integersOnly);e.extend(this,i)},xLabels:t,font:e.fontString(this.options.scaleFontSize,this.options.scaleFontStyle,this.options.scaleFontFamily),lineWidth:this.options.scaleLineWidth,lineColor:this.options.scaleLineColor,gridLineWidth:this.options.scaleShowGridLines?this.options.scaleGridLineWidth:0,gridLineColor:this.options.scaleShowGridLines?this.options.scaleGridLineColor:"rgba(0,0,0,0)",padding:this.options.showScale?0:this.options.barShowStroke?this.options.barStrokeWidth:0,showLabels:this.options.scaleShowLabels,display:this.options.showScale};this.options.scaleOverride&&e.extend(n,{calculateYRange:e.noop,steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}),this.scale=new this.ScaleClass(n)},addData:function(t,i){e.each(t,function(t,e){this.datasets[e].bars.push(new this.BarClass({value:t,label:i,x:this.scale.calculateBarX(this.datasets.length,e,this.scale.valuesCount+1),y:this.scale.endPoint,width:this.scale.calculateBarWidth(this.datasets.length),base:this.scale.endPoint,strokeColor:this.datasets[e].strokeColor,fillColor:this.datasets[e].fillColor}))},this),this.scale.addXLabel(i),this.update()},removeData:function(){this.scale.removeXLabel(),e.each(this.datasets,function(t){t.bars.shift()},this),this.update()},reflow:function(){e.extend(this.BarClass.prototype,{y:this.scale.endPoint,base:this.scale.endPoint});var t=e.extend({height:this.chart.height,width:this.chart.width});this.scale.update(t)},draw:function(t){var i=t||1;this.clear();this.chart.ctx;this.scale.draw(i),e.each(this.datasets,function(t,s){e.each(t.bars,function(t,e){t.hasValue()&&(t.base=this.scale.endPoint,t.transition({x:this.scale.calculateBarX(this.datasets.length,s,e),y:this.scale.calculateY(t.value),width:this.scale.calculateBarWidth(this.datasets.length)},i).draw())},this)},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,percentageInnerCutout:50,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'};
|
11 |
-
i.Type.extend({name:"Doughnut",defaults:s,initialize:function(t){this.segments=[],this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,this.SegmentArc=i.Arc.extend({ctx:this.chart.ctx,x:this.chart.width/2,y:this.chart.height/2}),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.calculateTotal(t),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({value:t.value,outerRadius:this.options.animateScale?0:this.outerRadius,innerRadius:this.options.animateScale?0:this.outerRadius/100*this.options.percentageInnerCutout,fillColor:t.color,highlightColor:t.highlight||t.color,showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,startAngle:1.5*Math.PI,circumference:this.options.animateRotate?0:this.calculateCircumference(t.value),label:t.label})),e||(this.reflow(),this.update())},calculateCircumference:function(t){return 2*Math.PI*(t/this.total)},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=t.value},this)},update:function(){this.calculateTotal(this.segments),e.each(this.activeElements,function(t){t.restore(["fillColor"])}),e.each(this.segments,function(t){t.save()}),this.render()},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,e.each(this.segments,function(t){t.update({outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout})},this)},draw:function(t){var i=t?t:1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.calculateCircumference(t.value),outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout},i),t.endAngle=t.startAngle+t.circumference,t.draw(),0===e&&(t.startAngle=1.5*Math.PI),e<this.segments.length-1&&(this.segments[e+1].startAngle=t.endAngle)},this)}}),i.types.Doughnut.extend({name:"Pie",defaults:e.merge(s,{percentageInnerCutout:0})})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,bezierCurve:!0,bezierCurveTension:.4,pointDot:!0,pointDotRadius:4,pointDotStrokeWidth:1,pointHitDetectionRadius:20,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].strokeColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"Line",defaults:s,initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx,inRange:function(t){return Math.pow(t-this.x,2)<Math.pow(this.radius+this.hitDetectionRadius,2)}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this),this.buildScale(t.labels),this.eachPoints(function(t,i){e.extend(t,{x:this.scale.calculateX(i),y:this.scale.endPoint}),t.save()},this)},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachPoints(function(t){t.save()}),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.datasets,function(t){e.each(t.points,function(t){t.inRange(s.x,s.y)&&i.push(t)})},this),i},buildScale:function(t){var s=this,n=function(){var t=[];return s.eachPoints(function(i){t.push(i.value)}),t},o={templateString:this.options.scaleLabel,height:this.chart.height,width:this.chart.width,ctx:this.chart.ctx,textColor:this.options.scaleFontColor,fontSize:this.options.scaleFontSize,fontStyle:this.options.scaleFontStyle,fontFamily:this.options.scaleFontFamily,valuesCount:t.length,beginAtZero:this.options.scaleBeginAtZero,integersOnly:this.options.scaleIntegersOnly,calculateYRange:function(t){var i=e.calculateScaleRange(n(),t,this.fontSize,this.beginAtZero,this.integersOnly);e.extend(this,i)},xLabels:t,font:e.fontString(this.options.scaleFontSize,this.options.scaleFontStyle,this.options.scaleFontFamily),lineWidth:this.options.scaleLineWidth,lineColor:this.options.scaleLineColor,gridLineWidth:this.options.scaleShowGridLines?this.options.scaleGridLineWidth:0,gridLineColor:this.options.scaleShowGridLines?this.options.scaleGridLineColor:"rgba(0,0,0,0)",padding:this.options.showScale?0:this.options.pointDotRadius+this.options.pointDotStrokeWidth,showLabels:this.options.scaleShowLabels,display:this.options.showScale};this.options.scaleOverride&&e.extend(o,{calculateYRange:e.noop,steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}),this.scale=new i.Scale(o)},addData:function(t,i){e.each(t,function(t,e){this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:this.scale.calculateX(this.scale.valuesCount+1),y:this.scale.endPoint,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.addXLabel(i),this.update()},removeData:function(){this.scale.removeXLabel(),e.each(this.datasets,function(t){t.points.shift()},this),this.update()},reflow:function(){var t=e.extend({height:this.chart.height,width:this.chart.width});this.scale.update(t)},draw:function(t){var i=t||1;this.clear();var s=this.chart.ctx,n=function(t){return null!==t.value},o=function(t,i,s){return e.findNextWhere(i,n,s)||t},a=function(t,i,s){return e.findPreviousWhere(i,n,s)||t};this.scale.draw(i),e.each(this.datasets,function(t){var h=e.where(t.points,n);e.each(t.points,function(t,e){t.hasValue()&&t.transition({y:this.scale.calculateY(t.value),x:this.scale.calculateX(e)},i)},this),this.options.bezierCurve&&e.each(h,function(t,i){var s=i>0&&i<h.length-1?this.options.bezierCurveTension:0;t.controlPoints=e.splineCurve(a(t,h,i),t,o(t,h,i),s),t.controlPoints.outer.y>this.scale.endPoint?t.controlPoints.outer.y=this.scale.endPoint:t.controlPoints.outer.y<this.scale.startPoint&&(t.controlPoints.outer.y=this.scale.startPoint),t.controlPoints.inner.y>this.scale.endPoint?t.controlPoints.inner.y=this.scale.endPoint:t.controlPoints.inner.y<this.scale.startPoint&&(t.controlPoints.inner.y=this.scale.startPoint)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(h,function(t,i){if(0===i)s.moveTo(t.x,t.y);else if(this.options.bezierCurve){var e=a(t,h,i);s.bezierCurveTo(e.controlPoints.outer.x,e.controlPoints.outer.y,t.controlPoints.inner.x,t.controlPoints.inner.y,t.x,t.y)}else s.lineTo(t.x,t.y)},this),s.stroke(),this.options.datasetFill&&h.length>0&&(s.lineTo(h[h.length-1].x,this.scale.endPoint),s.lineTo(h[0].x,this.scale.endPoint),s.fillStyle=t.fillColor,s.closePath(),s.fill()),e.each(h,function(t){t.draw()})},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBeginAtZero:!0,scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,scaleShowLine:!0,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"PolarArea",defaults:s,initialize:function(t){this.segments=[],this.SegmentArc=i.Arc.extend({showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,ctx:this.chart.ctx,innerRadius:0,x:this.chart.width/2,y:this.chart.height/2}),this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,lineArc:!0,width:this.chart.width,height:this.chart.height,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,valuesCount:t.length}),this.updateScaleRange(t),this.scale.update(),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({fillColor:t.color,highlightColor:t.highlight||t.color,label:t.label,value:t.value,outerRadius:this.options.animateScale?0:this.scale.calculateCenterOffset(t.value),circumference:this.options.animateRotate?0:this.scale.getCircumference(),startAngle:1.5*Math.PI})),e||(this.reflow(),this.update())},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=t.value},this),this.scale.valuesCount=this.segments.length},updateScaleRange:function(t){var i=[];e.each(t,function(t){i.push(t.value)});var s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s,{size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2})},update:function(){this.calculateTotal(this.segments),e.each(this.segments,function(t){t.save()}),this.render()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.updateScaleRange(this.segments),this.scale.update(),e.extend(this.scale,{xCenter:this.chart.width/2,yCenter:this.chart.height/2}),e.each(this.segments,function(t){t.update({outerRadius:this.scale.calculateCenterOffset(t.value)})},this)},draw:function(t){var i=t||1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.scale.getCircumference(),outerRadius:this.scale.calculateCenterOffset(t.value)},i),t.endAngle=t.startAngle+t.circumference,0===e&&(t.startAngle=1.5*Math.PI),e<this.segments.length-1&&(this.segments[e+1].startAngle=t.endAngle),t.draw()},this),this.scale.draw()}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers;i.Type.extend({name:"Radar",defaults:{scaleShowLine:!0,angleShowLineOut:!0,scaleShowLabels:!1,scaleBeginAtZero:!0,angleLineColor:"rgba(0,0,0,.1)",angleLineWidth:1,pointLabelFontFamily:"'Arial'",pointLabelFontStyle:"normal",pointLabelFontSize:10,pointLabelFontColor:"#666",pointDot:!0,pointDotRadius:3,pointDotStrokeWidth:1,pointHitDetectionRadius:20,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].strokeColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'},initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx}),this.datasets=[],this.buildScale(t),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){var o;this.scale.animation||(o=this.scale.getPointPosition(n,this.scale.calculateCenterOffset(e))),s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,x:this.options.animation?this.scale.xCenter:o.x,y:this.options.animation?this.scale.yCenter:o.y,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this)},this),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=e.getRelativePosition(t),s=e.getAngleFromPoint({x:this.scale.xCenter,y:this.scale.yCenter},i),n=2*Math.PI/this.scale.valuesCount,o=Math.round((s.angle-1.5*Math.PI)/n),a=[];return(o>=this.scale.valuesCount||0>o)&&(o=0),s.distance<=this.scale.drawingArea&&e.each(this.datasets,function(t){a.push(t.points[o])}),a},buildScale:function(t){this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,angleLineColor:this.options.angleLineColor,angleLineWidth:this.options.angleShowLineOut?this.options.angleLineWidth:0,pointLabelFontColor:this.options.pointLabelFontColor,pointLabelFontSize:this.options.pointLabelFontSize,pointLabelFontFamily:this.options.pointLabelFontFamily,pointLabelFontStyle:this.options.pointLabelFontStyle,height:this.chart.height,width:this.chart.width,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,labels:t.labels,valuesCount:t.datasets[0].data.length}),this.scale.setScaleSize(),this.updateScaleRange(t.datasets),this.scale.buildYLabels()},updateScaleRange:function(t){var i=function(){var i=[];return e.each(t,function(t){t.data?i=i.concat(t.data):e.each(t.points,function(t){i.push(t.value)})}),i}(),s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s)},addData:function(t,i){this.scale.valuesCount++,e.each(t,function(t,e){var s=this.scale.getPointPosition(this.scale.valuesCount,this.scale.calculateCenterOffset(t));this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:s.x,y:s.y,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.labels.push(i),this.reflow(),this.update()},removeData:function(){this.scale.valuesCount--,this.scale.labels.shift(),e.each(this.datasets,function(t){t.points.shift()},this),this.reflow(),this.update()},update:function(){this.eachPoints(function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.scale,{width:this.chart.width,height:this.chart.height,size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2}),this.updateScaleRange(this.datasets),this.scale.setScaleSize(),this.scale.buildYLabels()},draw:function(t){var i=t||1,s=this.chart.ctx;this.clear(),this.scale.draw(),e.each(this.datasets,function(t){e.each(t.points,function(t,e){t.hasValue()&&t.transition(this.scale.getPointPosition(e,this.scale.calculateCenterOffset(t.value)),i)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(t.points,function(t,i){0===i?s.moveTo(t.x,t.y):s.lineTo(t.x,t.y)},this),s.closePath(),s.stroke(),s.fillStyle=t.fillColor,s.fill(),e.each(t.points,function(t){t.hasValue()&&t.draw()})},this)}})}.call(this);
|
1 |
/*!
|
2 |
+
* Chart.js v2.9.3
|
3 |
+
* https://www.chartjs.org
|
4 |
+
* (c) 2019 Chart.js Contributors
|
5 |
+
* Released under the MIT License
|
|
|
|
|
|
|
6 |
*/
|
7 |
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(function(){try{return require("moment")}catch(t){}}()):"function"==typeof define&&define.amd?define(["require"],(function(t){return e(function(){try{return t("moment")}catch(t){}}())})):(t=t||self).Chart=e(t.moment)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},n=function(t,e){return t(e={exports:{}},e.exports),e.exports}((function(t){var n={};for(var i in e)e.hasOwnProperty(i)&&(n[e[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=n[t];if(i)return i;var a,r,o,s=1/0;for(var l in e)if(e.hasOwnProperty(l)){var u=e[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d<s&&(s=d,a=l)}return a},a.keyword.rgb=function(t){return e[t]},a.rgb.xyz=function(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));n.rgb,n.hsl,n.hsv,n.hwb,n.cmyk,n.xyz,n.lab,n.lch,n.hex,n.keyword,n.ansi16,n.ansi256,n.hcg,n.apple,n.gray;function i(t){var e=function(){for(var t={},e=Object.keys(n),i=e.length,a=0;a<i;a++)t[e[a]]={distance:-1,parent:null};return t}(),i=[t];for(e[t].distance=0;i.length;)for(var a=i.pop(),r=Object.keys(n[a]),o=r.length,s=0;s<o;s++){var l=r[s],u=e[l];-1===u.distance&&(u.distance=e[a].distance+1,u.parent=a,i.unshift(l))}return e}function a(t,e){return function(n){return e(t(n))}}function r(t,e){for(var i=[e[t].parent,t],r=n[e[t].parent][t],o=e[t].parent;e[o].parent;)i.unshift(e[o].parent),r=a(n[e[o].parent][o],r),o=e[o].parent;return r.conversion=i,r}var o={};Object.keys(n).forEach((function(t){o[t]={},Object.defineProperty(o[t],"channels",{value:n[t].channels}),Object.defineProperty(o[t],"labels",{value:n[t].labels});var e=function(t){for(var e=i(t),n={},a=Object.keys(e),o=a.length,s=0;s<o;s++){var l=a[s];null!==e[l].parent&&(n[l]=r(l,e))}return n}(t);Object.keys(e).forEach((function(n){var i=e[n];o[t][n]=function(t){var e=function(e){if(null==e)return e;arguments.length>1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a<i;a++)n[a]=Math.round(n[a]);return n};return"conversion"in t&&(e.conversion=t.conversion),e}(i),o[t][n].raw=function(t){var e=function(e){return null==e?e:(arguments.length>1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var s=o,l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},u={getRgba:d,getHsla:h,getRgb:function(t){var e=d(t);return e&&e.slice(0,3)},getHsl:function(t){var e=h(t);return e&&e.slice(0,3)},getHwb:c,getAlpha:function(t){var e=d(t);if(e)return e[3];if(e=h(t))return e[3];if(e=c(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+v(t[0])+v(t[1])+v(t[2])+(e>=0&&e<1?v(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:f,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:g,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return b[t.slice(0,3)]}};function d(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;r<e.length;r++)e[r]=parseInt(i[r]+i[r],16);a&&(n=Math.round(parseInt(a+a,16)/255*100)/100)}else if(i=t.match(/^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i)){a=i[2],i=i[1];for(r=0;r<e.length;r++)e[r]=parseInt(i.slice(2*r,2*r+2),16);a&&(n=Math.round(parseInt(a,16)/255*100)/100)}else if(i=t.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(r=0;r<e.length;r++)e[r]=parseInt(i[r+1]);n=parseFloat(i[4])}else if(i=t.match(/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(r=0;r<e.length;r++)e[r]=Math.round(2.55*parseFloat(i[r+1]));n=parseFloat(i[4])}else if(i=t.match(/(\w+)/)){if("transparent"==i[1])return[0,0,0,0];if(!(e=l[i[1]]))return}for(r=0;r<e.length;r++)e[r]=m(e[r],0,255);return n=n||0==n?m(n,0,1):1,e[3]=n,e}}function h(t){if(t){var e=t.match(/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var n=parseFloat(e[4]);return[m(parseInt(e[1]),0,360),m(parseFloat(e[2]),0,100),m(parseFloat(e[3]),0,100),m(isNaN(n)?1:n,0,1)]}}}function c(t){if(t){var e=t.match(/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var n=parseFloat(e[4]);return[m(parseInt(e[1]),0,360),m(parseFloat(e[2]),0,100),m(parseFloat(e[3]),0,100),m(isNaN(n)?1:n,0,1)]}}}function f(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function g(t,e){return"rgba("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%, "+(e||t[3]||1)+")"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e,n){return Math.min(Math.max(e,t),n)}function v(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var b={};for(var x in l)b[l[x]]=x;var y=function(t){return t instanceof y?t:this instanceof y?(this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1},void("string"==typeof t?(e=u.getRgba(t))?this.setValues("rgb",e):(e=u.getHsla(t))?this.setValues("hsl",e):(e=u.getHwb(t))&&this.setValues("hwb",e):"object"==typeof t&&(void 0!==(e=t).r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e)))):new y(t);var e};y.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t=(t%=360)<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return u.hexString(this.values.rgb)},rgbString:function(){return u.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return u.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return u.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return u.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return u.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return u.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return u.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new y,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},y.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},y.prototype.setValues=function(t,e){var n,i,a=this.values,r=this.spaces,o=this.maxes,l=1;if(this.valid=!0,"alpha"===t)l=e;else if(e.length)a[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];l=e.a}else if(void 0!==e[r[t][0]]){var u=r[t];for(n=0;n<t.length;n++)a[t][n]=e[u[n]];l=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===l?a.alpha:l)),"alpha"===t)return!1;for(n=0;n<t.length;n++)i=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(i);for(var d in r)d!==t&&(a[d]=s[t][d](a[t]));return!0},y.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},y.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:n===i[e]?this:(i[e]=n,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=y);var _,k=y,w={noop:function(){},uid:(_=0,function(){return _++}),isNullOrUndef:function(t){return null==t},isArray:function(t){if(Array.isArray&&Array.isArray(t))return!0;var e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},isFinite:function(t){return("number"==typeof t||t instanceof Number)&&isFinite(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,n){return w.valueOrDefault(w.isArray(t)?t[e]:t,n)},callback:function(t,e,n){if(t&&"function"==typeof t.call)return t.apply(n,e)},each:function(t,e,n,i){var a,r,o;if(w.isArray(t))if(r=t.length,i)for(a=r-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;a<r;a++)e.call(n,t[a],a);else if(w.isObject(t))for(r=(o=Object.keys(t)).length,a=0;a<r;a++)e.call(n,t[o[a]],o[a])},arrayEquals:function(t,e){var n,i,a,r;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;n<i;++n)if(a=t[n],r=e[n],a instanceof Array&&r instanceof Array){if(!w.arrayEquals(a,r))return!1}else if(a!==r)return!1;return!0},clone:function(t){if(w.isArray(t))return t.map(w.clone);if(w.isObject(t)){for(var e={},n=Object.keys(t),i=n.length,a=0;a<i;++a)e[n[a]]=w.clone(t[n[a]]);return e}return t},_merger:function(t,e,n,i){var a=e[t],r=n[t];w.isObject(a)&&w.isObject(r)?w.merge(a,r,i):e[t]=w.clone(r)},_mergerIf:function(t,e,n){var i=e[t],a=n[t];w.isObject(i)&&w.isObject(a)?w.mergeIf(i,a):e.hasOwnProperty(t)||(e[t]=w.clone(a))},merge:function(t,e,n){var i,a,r,o,s,l=w.isArray(e)?e:[e],u=l.length;if(!w.isObject(t))return t;for(i=(n=n||{}).merger||w._merger,a=0;a<u;++a)if(e=l[a],w.isObject(e))for(s=0,o=(r=Object.keys(e)).length;s<o;++s)i(r[s],t,e,n);return t},mergeIf:function(t,e){return w.merge(t,e,{merger:w._mergerIf})},extend:Object.assign||function(t){return w.merge(t,[].slice.call(arguments,1),{merger:function(t,e,n){e[t]=n[t]}})},inherits:function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=w.inherits,t&&w.extend(n.prototype,t),n.__super__=e.prototype,n},_deprecated:function(t,e,n,i){void 0!==e&&console.warn(t+': "'+n+'" is deprecated. Please use "'+i+'" instead')}},M=w;w.callCallback=w.callback,w.indexOf=function(t,e,n){return Array.prototype.indexOf.call(t,e,n)},w.getValueOrDefault=w.valueOrDefault,w.getValueAtIndexOrDefault=w.valueAtIndexOrDefault;var S={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=1)*t*t+1},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=1)*t*t*t*t+1},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return 1-Math.cos(t*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-S.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*S.easeInBounce(2*t):.5*S.easeOutBounce(2*t-1)+.5}},C={effects:S};M.easingEffects=S;var P=Math.PI,A=P/180,D=2*P,T=P/2,I=P/4,F=2*P/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),s<u&&l<d?(t.arc(s,l,o,-P,-T),t.arc(u,l,o,-T,0),t.arc(u,d,o,0,T),t.arc(s,d,o,T,P)):s<u?(t.moveTo(s,n),t.arc(u,l,o,-T,T),t.arc(s,l,o,T,P+T)):l<d?(t.arc(s,l,o,-P,0),t.arc(s,d,o,0,P)):t.arc(s,l,o,-P,P),t.closePath(),t.moveTo(e,n)}else t.rect(e,n,i,a)},drawPoint:function(t,e,n,i,a,r){var o,s,l,u,d,h=(r||0)*A;if(e&&"object"==typeof e&&("[object HTMLImageElement]"===(o=e.toString())||"[object HTMLCanvasElement]"===o))return t.save(),t.translate(i,a),t.rotate(h),t.drawImage(e,-e.width/2,-e.height/2,e.width,e.height),void t.restore();if(!(isNaN(n)||n<=0)){switch(t.beginPath(),e){default:t.arc(i,a,n,0,D),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=F,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=F,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),t.closePath();break;case"rectRounded":u=n-(d=.516*n),s=Math.cos(h+I)*u,l=Math.sin(h+I)*u,t.arc(i-s,a-l,d,h-P,h-T),t.arc(i+l,a-s,d,h-T,h),t.arc(i+s,a+l,d,h,h+T),t.arc(i-l,a+s,d,h+T,h+P),t.closePath();break;case"rect":if(!r){u=Math.SQRT1_2*n,t.rect(i-u,a-u,2*u,2*u);break}h+=I;case"rectRot":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+l,a-s),t.lineTo(i+s,a+l),t.lineTo(i-l,a+s),t.closePath();break;case"crossRot":h+=I;case"cross":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s);break;case"star":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s),h+=I,s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s);break;case"line":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l);break;case"dash":t.moveTo(i,a),t.lineTo(i+Math.cos(h)*n,a+Math.sin(h)*n)}t.fill(),t.stroke()}},_isPointInArea:function(t,e){return t.x>e.left-1e-6&&t.x<e.right+1e-6&&t.y>e.top-1e-6&&t.y<e.bottom+1e-6},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,n,i){var a=n.steppedLine;if(a){if("middle"===a){var r=(e.x+n.x)/2;t.lineTo(r,i?n.y:e.y),t.lineTo(r,i?e.y:n.y)}else"after"===a&&!i||"after"!==a&&i?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y);t.lineTo(n.x,n.y)}else n.tension?t.bezierCurveTo(i?e.controlPointPreviousX:e.controlPointNextX,i?e.controlPointPreviousY:e.controlPointNextY,i?n.controlPointNextX:n.controlPointPreviousX,i?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):t.lineTo(n.x,n.y)}},O=L;M.clear=L.clear,M.drawRoundedRectangle=function(t){t.beginPath(),L.roundedRect.apply(L,arguments)};var R={_set:function(t,e){return M.merge(this[t]||(this[t]={}),e)}};R._set("global",{defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",defaultLineHeight:1.2,showLines:!0});var z=R,N=M.valueOrDefault;var B={toLineHeight:function(t,e){var n=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!n||"normal"===n[1])return 1.2*e;switch(t=+n[2],n[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,n,i,a;return M.isObject(t)?(e=+t.top||0,n=+t.right||0,i=+t.bottom||0,a=+t.left||0):e=n=i=a=+t||0,{top:e,right:n,bottom:i,left:a,height:e+i,width:a+n}},_parseFont:function(t){var e=z.global,n=N(t.fontSize,e.defaultFontSize),i={family:N(t.fontFamily,e.defaultFontFamily),lineHeight:M.options.toLineHeight(N(t.lineHeight,e.defaultLineHeight),n),size:n,style:N(t.fontStyle,e.defaultFontStyle),weight:null,string:""};return i.string=function(t){return!t||M.isNullOrUndef(t.size)||M.isNullOrUndef(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}(i),i},resolve:function(t,e,n,i){var a,r,o,s=!0;for(a=0,r=t.length;a<r;++a)if(void 0!==(o=t[a])&&(void 0!==e&&"function"==typeof o&&(o=o(e),s=!1),void 0!==n&&M.isArray(o)&&(o=o[n],s=!1),void 0!==o))return i&&!s&&(i.cacheable=!1),o}},E={_factorize:function(t){var e,n=[],i=Math.sqrt(t);for(e=1;e<i;e++)t%e==0&&(n.push(e),n.push(t/e));return i===(0|i)&&n.push(i),n.sort((function(t,e){return t-e})).pop(),n},log10:Math.log10||function(t){var e=Math.log(t)*Math.LOG10E,n=Math.round(e);return t===Math.pow(10,n)?n:e}},W=E;M.log10=E.log10;var V=M,H=C,j=O,q=B,U=W,Y={getRtlAdapter:function(t,e,n){return t?function(t,e){return{x:function(n){return t+t+e-n},setWidth:function(t){e=t},textAlign:function(t){return"center"===t?t:"right"===t?"left":"right"},xPlus:function(t,e){return t-e},leftForLtr:function(t,e){return t-e}}}(e,n):{x:function(t){return t},setWidth:function(t){},textAlign:function(t){return t},xPlus:function(t,e){return t+e},leftForLtr:function(t,e){return t}}},overrideTextDirection:function(t,e){var n,i;"ltr"!==e&&"rtl"!==e||(i=[(n=t.canvas.style).getPropertyValue("direction"),n.getPropertyPriority("direction")],n.setProperty("direction",e,"important"),t.prevTextDirection=i)},restoreTextDirection:function(t){var e=t.prevTextDirection;void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}};V.easing=H,V.canvas=j,V.options=q,V.math=U,V.rtl=Y;var G=function(t){V.extend(this,t),this.initialize.apply(this,arguments)};V.extend(G.prototype,{_type:void 0,initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=V.extend({},t._model)),t._start={},t},transition:function(t){var e=this,n=e._model,i=e._start,a=e._view;return n&&1!==t?(a||(a=e._view={}),i||(i=e._start={}),function(t,e,n,i){var a,r,o,s,l,u,d,h,c,f=Object.keys(n);for(a=0,r=f.length;a<r;++a)if(u=n[o=f[a]],e.hasOwnProperty(o)||(e[o]=u),(s=e[o])!==u&&"_"!==o[0]){if(t.hasOwnProperty(o)||(t[o]=s),(d=typeof u)===typeof(l=t[o]))if("string"===d){if((h=k(l)).valid&&(c=k(u)).valid){e[o]=c.mix(h,i).rgbString();continue}}else if(V.isFinite(l)&&V.isFinite(u)){e[o]=l+(u-l)*i;continue}e[o]=u}}(i,a,n,t),e):(e._view=V.extend({},n),e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return V.isNumber(this._model.x)&&V.isNumber(this._model.y)}}),G.extend=V.inherits;var X=G,K=X.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),Z=K;Object.defineProperty(K.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(K.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}}),z._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:V.noop,onComplete:V.noop}});var $={animations:[],request:null,addAnimation:function(t,e,n,i){var a,r,o=this.animations;for(e.chart=t,e.startTime=Date.now(),e.duration=n,i||(t.animating=!0),a=0,r=o.length;a<r;++a)if(o[a].chart===t)return void(o[a]=e);o.push(e),1===o.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var e=V.findIndex(this.animations,(function(e){return e.chart===t}));-1!==e&&(this.animations.splice(e,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=V.requestAnimFrame.call(window,(function(){t.request=null,t.startDigest()})))},startDigest:function(){this.advance(),this.animations.length>0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r<a.length;)e=(t=a[r]).chart,n=t.numSteps,i=Math.floor((Date.now()-t.startTime)/t.duration*n)+1,t.currentStep=Math.min(i,n),V.callback(t.render,[e,t],e),V.callback(t.onAnimationProgress,[t],e),t.currentStep>=n?(V.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},J=V.options.resolve,Q=["push","pop","shift","splice","unshift"];function tt(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(Q.forEach((function(e){delete t[e]})),delete t._chartjs)}}var et=function(t,e){this.initialize(t,e)};V.extend(et.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&tt(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;t<e;++t)a[t]=a[t]||this.createMetaData(t);n.dataset=n.dataset||this.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t,e,n=this,i=n.getDataset(),a=i.data||(i.data=[]);n._data!==a&&(n._data&&tt(n._data,n),a&&Object.isExtensible(a)&&(e=n,(t=a)._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),Q.forEach((function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),i=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),a=i.apply(this,e);return V.each(t._chartjs.listeners,(function(t){"function"==typeof t[n]&&t[n].apply(t,e)})),a}})})))),n._data=a),n.resyncElements()},_configure:function(){this._config=V.merge({},[this.chart.options.datasets[this._type],this.getDataset()],{merger:function(t,e,n){"_meta"!==t&&"data"!==t&&V._merger(t,e,n)}})},_update:function(t){this._configure(),this._cachedDataOpts=null,this.update(t)},update:V.noop,transition:function(t){for(var e=this.getMeta(),n=e.data||[],i=n.length,a=0;a<i;++a)n[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],n=e.length,i=0;for(t.dataset&&t.dataset.draw();i<n;++i)e[i].draw()},getStyle:function(t){var e,n=this.getMeta(),i=n.dataset;return this._configure(),i&&void 0===t?e=this._resolveDatasetElementOptions(i||{}):(t=t||0,e=this._resolveDataElementOptions(n.data[t]||{},t)),!1!==e.fill&&null!==e.fill||(e.backgroundColor=e.borderColor),e},_resolveDatasetElementOptions:function(t,e){var n,i,a,r,o=this,s=o.chart,l=o._config,u=t.custom||{},d=s.options.elements[o.datasetElementType.prototype._type]||{},h=o._datasetElementOptions,c={},f={chart:s,dataset:o.getDataset(),datasetIndex:o.index,hover:e};for(n=0,i=h.length;n<i;++n)a=h[n],r=e?"hover"+a.charAt(0).toUpperCase()+a.slice(1):a,c[a]=J([u[r],l[r],d[r]],f);return c},_resolveDataElementOptions:function(t,e){var n=this,i=t&&t.custom,a=n._cachedDataOpts;if(a&&!i)return a;var r,o,s,l,u=n.chart,d=n._config,h=u.options.elements[n.dataElementType.prototype._type]||{},c=n._dataElementOptions,f={},g={chart:u,dataIndex:e,dataset:n.getDataset(),datasetIndex:n.index},p={cacheable:!i};if(i=i||{},V.isArray(c))for(o=0,s=c.length;o<s;++o)f[l=c[o]]=J([i[l],d[l],h[l]],g,e,p);else for(o=0,s=(r=Object.keys(c)).length;o<s;++o)f[l=r[o]]=J([i[l],d[c[l]],d[l],h[l]],g,e,p);return p.cacheable&&(n._cachedDataOpts=Object.freeze(f)),f},removeHoverStyle:function(t){V.merge(t._model,t.$previousStyle||{}),delete t.$previousStyle},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model,r=V.getHoverColor;t.$previousStyle={backgroundColor:a.backgroundColor,borderColor:a.borderColor,borderWidth:a.borderWidth},a.backgroundColor=J([i.hoverBackgroundColor,e.hoverBackgroundColor,r(a.backgroundColor)],void 0,n),a.borderColor=J([i.hoverBorderColor,e.hoverBorderColor,r(a.borderColor)],void 0,n),a.borderWidth=J([i.hoverBorderWidth,e.hoverBorderWidth,a.borderWidth],void 0,n)},_removeDatasetHoverStyle:function(){var t=this.getMeta().dataset;t&&this.removeHoverStyle(t)},_setDatasetHoverStyle:function(){var t,e,n,i,a,r,o=this.getMeta().dataset,s={};if(o){for(r=o._model,a=this._resolveDatasetElementOptions(o,!0),t=0,e=(i=Object.keys(a)).length;t<e;++t)s[n=i[t]]=r[n],r[n]=a[n];o.$previousStyle=s}},resyncElements:function(){var t=this.getMeta(),e=this.getDataset().data,n=t.data.length,i=e.length;i<n?t.data.splice(i,n-i):i>n&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;n<e;++n)this.addElementAndReset(t+n)},onDataPush:function(){var t=arguments.length;this.insertElements(this.getDataset().data.length-t,t)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),et.extend=V.inherits;var nt=et,it=2*Math.PI;function at(t,e){var n=e.startAngle,i=e.endAngle,a=e.pixelMargin,r=a/e.outerRadius,o=e.x,s=e.y;t.beginPath(),t.arc(o,s,e.outerRadius,n-r,i+r),e.innerRadius>a?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function rt(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+it,at(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=it,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+it,n.startAngle,!0),a=0;a<n.fullCircles;++a)t.stroke();for(t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.startAngle+it),a=0;a<n.fullCircles;++a)t.stroke()}(t,e,n,i),i&&at(t,n),t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.endAngle),t.arc(n.x,n.y,n.innerRadius,n.endAngle,n.startAngle,!0),t.closePath(),t.stroke()}z._set("global",{elements:{arc:{backgroundColor:z.global.defaultColor,borderColor:"#fff",borderWidth:2,borderAlign:"center"}}});var ot=X.extend({_type:"arc",inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,e){var n=this._view;if(n){for(var i=V.getAngleFromPoint(n,{x:t,y:e}),a=i.angle,r=i.distance,o=n.startAngle,s=n.endAngle;s<o;)s+=it;for(;a>s;)a-=it;for(;a<o;)a+=it;var l=a>=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/it)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+it,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;t<a.fullCircles;++t)e.fill();a.endAngle=a.startAngle+n.circumference%it}e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),e.fill(),n.borderWidth&&rt(e,n,a),e.restore()}}),st=V.valueOrDefault,lt=z.global.defaultColor;z._set("global",{elements:{line:{tension:.4,backgroundColor:lt,borderWidth:3,borderColor:lt,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}});var ut=X.extend({_type:"line",draw:function(){var t,e,n,i=this,a=i._view,r=i._chart.ctx,o=a.spanGaps,s=i._children.slice(),l=z.global,u=l.elements.line,d=-1,h=i._loop;if(s.length){if(i._loop){for(t=0;t<s.length;++t)if(e=V.previousItem(s,t),!s[t]._view.skip&&e._view.skip){s=s.slice(t).concat(s.slice(0,t)),h=o;break}h&&s.push(s[0])}for(r.save(),r.lineCap=a.borderCapStyle||u.borderCapStyle,r.setLineDash&&r.setLineDash(a.borderDash||u.borderDash),r.lineDashOffset=st(a.borderDashOffset,u.borderDashOffset),r.lineJoin=a.borderJoinStyle||u.borderJoinStyle,r.lineWidth=st(a.borderWidth,u.borderWidth),r.strokeStyle=a.borderColor||l.defaultColor,r.beginPath(),(n=s[0]._view).skip||(r.moveTo(n.x,n.y),d=0),t=1;t<s.length;++t)n=s[t]._view,e=-1===d?V.previousItem(s,t):s[d],n.skip||(d!==t-1&&!o||-1===d?r.moveTo(n.x,n.y):V.canvas.lineTo(r,e._view,n),d=t);h&&r.closePath(),r.stroke(),r.restore()}}}),dt=V.valueOrDefault,ht=z.global.defaultColor;function ct(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}z._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:ht,borderColor:ht,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}});var ft=X.extend({_type:"point",inRange:function(t,e){var n=this._view;return!!n&&Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2)},inLabelRange:ct,inXRange:ct,inYRange:function(t){var e=this._view;return!!e&&Math.abs(t-e.y)<e.radius+e.hitRadius},getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(t){var e=this._view,n=this._chart.ctx,i=e.pointStyle,a=e.rotation,r=e.radius,o=e.x,s=e.y,l=z.global,u=l.defaultColor;e.skip||(void 0===t||V.canvas._isPointInArea(e,t))&&(n.strokeStyle=e.borderColor||u,n.lineWidth=dt(e.borderWidth,l.elements.point.borderWidth),n.fillStyle=e.backgroundColor||u,V.canvas.drawPoint(n,i,r,o,s,a))}}),gt=z.global.defaultColor;function pt(t){return t&&void 0!==t.width}function mt(t){var e,n,i,a,r;return pt(t)?(r=t.width/2,e=t.x-r,n=t.x+r,i=Math.min(t.y,t.base),a=Math.max(t.y,t.base)):(r=t.height/2,e=Math.min(t.x,t.base),n=Math.max(t.x,t.base),i=t.y-r,a=t.y+r),{left:e,top:i,right:n,bottom:a}}function vt(t,e,n){return t===e?n:t===n?e:t}function bt(t,e,n){var i,a,r,o,s=t.borderWidth,l=function(t){var e=t.borderSkipped,n={};return e?(t.horizontal?t.base>t.x&&(e=vt(e,"left","right")):t.base<t.y&&(e=vt(e,"bottom","top")),n[e]=!0,n):n}(t);return V.isObject(s)?(i=+s.top||0,a=+s.right||0,r=+s.bottom||0,o=+s.left||0):i=a=r=o=+s||0,{t:l.top||i<0?0:i>n?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function xt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&mt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}z._set("global",{elements:{rectangle:{backgroundColor:gt,borderColor:gt,borderSkipped:"bottom",borderWidth:0}}});var yt=X.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=mt(t),n=e.right-e.left,i=e.bottom-e.top,a=bt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return xt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return pt(n)?xt(n,t,null):xt(n,null,e)},inXRange:function(t){return xt(this._view,t,null)},inYRange:function(t){return xt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return pt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return pt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),_t={},kt=ot,wt=ut,Mt=ft,St=yt;_t.Arc=kt,_t.Line=wt,_t.Point=Mt,_t.Rectangle=St;var Ct=V._deprecated,Pt=V.valueOrDefault;function At(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=V.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a<r;++a)o=Math.min(o,Math.abs(e[a]-e[a-1]));for(a=0,r=t.getTicks().length;a<r;++a)i=t.getPixelForTick(a),o=a>0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return V.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}z._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),z._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Dt=nt.extend({dataElementType:_t.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;nt.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Ct("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Ct("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Ct("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Ct("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Ct("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e<n;++e)this.updateElement(i[e],e,t)},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=i.getDataset(),o=i._resolveDataElementOptions(t,e);t._xScale=i.getScaleForId(a.xAxisID),t._yScale=i.getScaleForId(a.yAxisID),t._datasetIndex=i.index,t._index=e,t._model={backgroundColor:o.backgroundColor,borderColor:o.borderColor,borderSkipped:o.borderSkipped,borderWidth:o.borderWidth,datasetLabel:r.label,label:i.chart.data.labels[e]},V.isArray(r.data[e])&&(t._model.borderSkipped=null),i._updateElementGeometry(t,e,n,o),t.pivot()},_updateElementGeometry:function(t,e,n,i){var a=this,r=t._model,o=a._getValueScale(),s=o.getBasePixel(),l=o.isHorizontal(),u=a._ruler||a.getRuler(),d=a.calculateBarValuePixels(a.index,e,i),h=a.calculateBarIndexPixels(a.index,e,u,i);r.horizontal=l,r.base=n?s:d.base,r.x=l?n?s:d.head:h.center,r.y=l?h.center:n?s:d.head,r.height=l?h.size:void 0,r.width=l?void 0:h.size},_getStacks:function(t){var e,n,i=this._getIndexScale(),a=i._getMatchingVisibleMetas(this._type),r=i.options.stacked,o=a.length,s=[];for(e=0;e<o&&(n=a[e],(!1===r||-1===s.indexOf(n.stack)||void 0===r&&void 0===n.stack)&&s.push(n.stack),n.index!==t);++e);return s},getStackCount:function(){return this._getStacks().length},getStackIndex:function(t,e){var n=this._getStacks(t),i=void 0!==e?n.indexOf(e):-1;return-1===i?n.length-1:i},getRuler:function(){var t,e,n=this._getIndexScale(),i=[];for(t=0,e=this.getMeta().data.length;t<e;++t)i.push(n.getPixelForValue(null,t,this.index));return{pixels:i,start:n._startPixel,end:n._endPixel,stackCount:this.getStackCount(),scale:n}},calculateBarValuePixels:function(t,e,n){var i,a,r,o,s,l,u,d=this.chart,h=this._getValueScale(),c=h.isHorizontal(),f=d.data.datasets,g=h._getMatchingVisibleMetas(this._type),p=h._parseValue(f[t].data[e]),m=n.minBarLength,v=h.options.stacked,b=this.getMeta().stack,x=void 0===p.start?0:p.max>=0&&p.min>=0?p.min:p.max,y=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=h.getPixelForValue(x),l=(s=h.getPixelForValue(x+y))-o,void 0!==m&&Math.abs(l)<m&&(l=m,s=y>=0&&!c||y<0&&c?o-m:o+m),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t<a.length-1?a[t+1]:null,l=n.categoryPercentage;return null===o&&(o=r-(null===s?e.end-e.start:s-r)),null===s&&(s=r+r-o),i=r-(r-Math.min(o,s))/2*l,{chunk:Math.abs(s-o)/2*l/e.stackCount,ratio:n.barPercentage,start:i}}(e,n,i):At(e,n,i),r=this.getStackIndex(t,this.getMeta().stack),o=a.start+a.chunk*r+a.chunk/2,s=Math.min(Pt(i.maxBarThickness,1/0),a.chunk*a.ratio);return{base:o-s/2,head:o+s/2,center:o,size:s}},draw:function(){var t=this.chart,e=this._getValueScale(),n=this.getMeta().data,i=this.getDataset(),a=n.length,r=0;for(V.canvas.clipArea(t.ctx,t.chartArea);r<a;++r){var o=e._parseValue(i.data[r]);isNaN(o.min)||isNaN(o.max)||n[r].draw()}V.canvas.unclipArea(t.ctx)},_resolveDataElementOptions:function(){var t=this,e=V.extend({},nt.prototype._resolveDataElementOptions.apply(t,arguments)),n=t._getIndexScale().options,i=t._getValueScale().options;return e.barPercentage=Pt(n.barPercentage,e.barPercentage),e.barThickness=Pt(n.barThickness,e.barThickness),e.categoryPercentage=Pt(n.categoryPercentage,e.categoryPercentage),e.maxBarThickness=Pt(n.maxBarThickness,e.maxBarThickness),e.minBarLength=Pt(i.minBarLength,e.minBarLength),e}}),Tt=V.valueOrDefault,It=V.options.resolve;z._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}});var Ft=nt.extend({dataElementType:_t.Point,_dataElementOptions:["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle","rotation"],update:function(t){var e=this,n=e.getMeta().data;V.each(n,(function(n,i){e.updateElement(n,i,t)}))},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=t.custom||{},o=i.getScaleForId(a.xAxisID),s=i.getScaleForId(a.yAxisID),l=i._resolveDataElementOptions(t,e),u=i.getDataset().data[e],d=i.index,h=n?o.getPixelForDecimal(.5):o.getPixelForValue("object"==typeof u?u:NaN,e,d),c=n?s.getBasePixel():s.getPixelForValue(u,e,d);t._xScale=o,t._yScale=s,t._options=l,t._datasetIndex=d,t._index=e,t._model={backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,hitRadius:l.hitRadius,pointStyle:l.pointStyle,rotation:l.rotation,radius:n?0:l.radius,skip:r.skip||isNaN(h)||isNaN(c),x:h,y:c},t.pivot()},setHoverStyle:function(t){var e=t._model,n=t._options,i=V.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Tt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Tt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Tt(n.hoverBorderWidth,n.borderWidth),e.radius=n.radius+n.hoverRadius},_resolveDataElementOptions:function(t,e){var n=this,i=n.chart,a=n.getDataset(),r=t.custom||{},o=a.data[e]||{},s=nt.prototype._resolveDataElementOptions.apply(n,arguments),l={chart:i,dataIndex:e,dataset:a,datasetIndex:n.index};return n._cachedDataOpts===s&&(s=V.extend({},s)),s.radius=It([r.radius,o.r,n._config.radius,i.options.elements.point.radius],l,e),s}}),Lt=V.valueOrDefault,Ot=Math.PI,Rt=2*Ot,zt=Ot/2;z._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data,o=r.datasets,s=r.labels;if(a.setAttribute("class",t.id+"-legend"),o.length)for(e=0,n=o[0].data.length;e<n;++e)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return a.outerHTML},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map((function(n,i){var a=t.getDatasetMeta(0),r=a.controller.getStyle(i);return{text:n,fillStyle:r.backgroundColor,strokeStyle:r.borderColor,lineWidth:r.borderWidth,hidden:isNaN(e.datasets[0].data[i])||a.data[i].hidden,index:i}})):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r]&&(a.data[r].hidden=!a.data[r].hidden);o.update()}},cutoutPercentage:50,rotation:-zt,circumference:Rt,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.labels[t.index],i=": "+e.datasets[t.datasetIndex].data[t.index];return V.isArray(n)?(n=n.slice())[0]+=i:n+=i,n}}}});var Nt=nt.extend({dataElementType:_t.Arc,linkScales:V.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],getRingIndex:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var e,n,i,a,r=this,o=r.chart,s=o.chartArea,l=o.options,u=1,d=1,h=0,c=0,f=r.getMeta(),g=f.data,p=l.cutoutPercentage/100||0,m=l.circumference,v=r._getRingWeight(r.index);if(m<Rt){var b=l.rotation%Rt,x=(b+=b>=Ot?-Rt:b<-Ot?Rt:0)+m,y=Math.cos(b),_=Math.sin(b),k=Math.cos(x),w=Math.sin(x),M=b<=0&&x>=0||x>=Rt,S=b<=zt&&x>=zt||x>=Rt+zt,C=b<=-zt&&x>=-zt||x>=Ot+zt,P=b===-Ot||x>=Ot?-1:Math.min(y,y*p,k,k*p),A=C?-1:Math.min(_,_*p,w,w*p),D=M?1:Math.max(y,y*p,k,k*p),T=S?1:Math.max(_,_*p,w,w*p);u=(D-P)/2,d=(T-A)/2,h=-(D+P)/2,c=-(T+A)/2}for(i=0,a=g.length;i<a;++i)g[i]._options=r._resolveDataElementOptions(g[i],i);for(o.borderWidth=r.getMaxBorderWidth(),e=(s.right-s.left-o.borderWidth)/u,n=(s.bottom-s.top-o.borderWidth)/d,o.outerRadius=Math.max(Math.min(e,n)/2,0),o.innerRadius=Math.max(o.outerRadius*p,0),o.radiusLength=(o.outerRadius-o.innerRadius)/(r._getVisibleDatasetWeightTotal()||1),o.offsetX=h*o.outerRadius,o.offsetY=c*o.outerRadius,f.total=r.calculateTotal(),r.outerRadius=o.outerRadius-o.radiusLength*r._getRingWeightOffset(r.index),r.innerRadius=Math.max(r.outerRadius-o.radiusLength*v,0),i=0,a=g.length;i<a;++i)r.updateElement(g[i],i,t)},updateElement:function(t,e,n){var i=this,a=i.chart,r=a.chartArea,o=a.options,s=o.animation,l=(r.left+r.right)/2,u=(r.top+r.bottom)/2,d=o.rotation,h=o.rotation,c=i.getDataset(),f=n&&s.animateRotate?0:t.hidden?0:i.calculateCircumference(c.data[e])*(o.circumference/Rt),g=n&&s.animateScale?0:i.innerRadius,p=n&&s.animateScale?0:i.outerRadius,m=t._options||{};V.extend(t,{_datasetIndex:i.index,_index:e,_model:{backgroundColor:m.backgroundColor,borderColor:m.borderColor,borderWidth:m.borderWidth,borderAlign:m.borderAlign,x:l+a.offsetX,y:u+a.offsetY,startAngle:d,endAngle:h,circumference:f,outerRadius:p,innerRadius:g,label:V.valueAtIndexOrDefault(c.label,e,a.data.labels[e])}});var v=t._model;n&&s.animateRotate||(v.startAngle=0===e?o.rotation:i.getMeta().data[e-1]._model.endAngle,v.endAngle=v.startAngle+v.circumference),t.pivot()},calculateTotal:function(){var t,e=this.getDataset(),n=this.getMeta(),i=0;return V.each(n.data,(function(n,a){t=e.data[a],isNaN(t)||n.hidden||(i+=Math.abs(t))})),i},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?Rt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e<n;++e)if(d.isDatasetVisible(e)){t=(i=d.getDatasetMeta(e)).data,e!==this.index&&(r=i.controller);break}if(!t)return 0;for(e=0,n=t.length;e<n;++e)a=t[e],r?(r._configure(),o=r._resolveDataElementOptions(a,e)):o=a._options,"inner"!==o.borderAlign&&(s=o.borderWidth,u=(l=o.hoverBorderWidth)>(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=V.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&(e+=this._getRingWeight(n));return e},_getRingWeight:function(t){return Math.max(Lt(this.chart.data.datasets[t].weight,1),0)},_getVisibleDatasetWeightTotal:function(){return this._getRingWeightOffset(this.chart.data.datasets.length)}});z._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{type:"category",position:"left",offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{mode:"index",axis:"y"}}),z._set("global",{datasets:{horizontalBar:{categoryPercentage:.8,barPercentage:.9}}});var Bt=Dt.extend({_getValueScaleId:function(){return this.getMeta().xAxisID},_getIndexScaleId:function(){return this.getMeta().yAxisID}}),Et=V.valueOrDefault,Wt=V.options.resolve,Vt=V.canvas._isPointInArea;function Ht(t,e){var n=t&&t.options.ticks||{},i=n.reverse,a=void 0===n.min?e:0,r=void 0===n.max?e:0;return{start:i?r:a,end:i?a:r}}function jt(t,e,n){var i=n/2,a=Ht(t,i),r=Ht(e,i);return{top:r.end,right:a.end,bottom:r.start,left:a.start}}function qt(t){var e,n,i,a;return V.isObject(t)?(e=t.top,n=t.right,i=t.bottom,a=t.left):e=n=i=a=t,{top:e,right:n,bottom:i,left:a}}z._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}});var Ut=nt.extend({datasetElementType:_t.Line,dataElementType:_t.Point,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth","cubicInterpolationMode","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},update:function(t){var e,n,i=this,a=i.getMeta(),r=a.dataset,o=a.data||[],s=i.chart.options,l=i._config,u=i._showLine=Et(l.showLine,s.showLines);for(i._xScale=i.getScaleForId(a.xAxisID),i._yScale=i.getScaleForId(a.yAxisID),u&&(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),r._scale=i._yScale,r._datasetIndex=i.index,r._children=o,r._model=i._resolveDatasetElementOptions(r),r.pivot()),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(u&&0!==r._model.tension&&i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i,a,r=this,o=r.getMeta(),s=t.custom||{},l=r.getDataset(),u=r.index,d=l.data[e],h=r._xScale,c=r._yScale,f=o.dataset._model,g=r._resolveDataElementOptions(t,e);i=h.getPixelForValue("object"==typeof d?d:NaN,e,u),a=n?c.getBasePixel():r.calculatePointY(d,e,u),t._xScale=h,t._yScale=c,t._options=g,t._datasetIndex=u,t._index=e,t._model={x:i,y:a,skip:s.skip||isNaN(i)||isNaN(a),radius:g.radius,pointStyle:g.pointStyle,rotation:g.rotation,backgroundColor:g.backgroundColor,borderColor:g.borderColor,borderWidth:g.borderWidth,tension:Et(s.tension,f?f.tension:0),steppedLine:!!f&&f.steppedLine,hitRadius:g.hitRadius}},_resolveDatasetElementOptions:function(t){var e=this,n=e._config,i=t.custom||{},a=e.chart.options,r=a.elements.line,o=nt.prototype._resolveDatasetElementOptions.apply(e,arguments);return o.spanGaps=Et(n.spanGaps,a.spanGaps),o.tension=Et(n.lineTension,r.tension),o.steppedLine=Wt([i.steppedLine,n.steppedLine,r.stepped]),o.clip=qt(Et(n.clip,jt(e._xScale,e._yScale,o.borderWidth))),o},calculatePointY:function(t,e,n){var i,a,r,o,s,l,u,d=this.chart,h=this._yScale,c=0,f=0;if(h.options.stacked){for(s=+h.getRightValue(t),u=(l=d._getSortedVisibleDatasetMetas()).length,i=0;i<u&&(r=l[i]).index!==n;++i)a=d.data.datasets[r.index],"line"===r.type&&r.yAxisID===h.id&&((o=+h.getRightValue(a.data[e]))<0?f+=o||0:c+=o||0);return s<0?h.getPixelForValue(f+s):h.getPixelForValue(c+s)}return h.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,n,i,a=this.chart,r=this.getMeta(),o=r.dataset._model,s=a.chartArea,l=r.data||[];function u(t,e,n){return Math.max(Math.min(t,n),e)}if(o.spanGaps&&(l=l.filter((function(t){return!t._model.skip}))),"monotone"===o.cubicInterpolationMode)V.splineCurveMonotone(l);else for(t=0,e=l.length;t<e;++t)n=l[t]._model,i=V.splineCurve(V.previousItem(l,t)._model,n,V.nextItem(l,t)._model,o.tension),n.controlPointPreviousX=i.previous.x,n.controlPointPreviousY=i.previous.y,n.controlPointNextX=i.next.x,n.controlPointNextY=i.next.y;if(a.options.elements.line.capBezierPoints)for(t=0,e=l.length;t<e;++t)n=l[t]._model,Vt(n,s)&&(t>0&&Vt(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t<l.length-1&&Vt(l[t+1]._model,s)&&(n.controlPointNextX=u(n.controlPointNextX,s.left,s.right),n.controlPointNextY=u(n.controlPointNextY,s.top,s.bottom)))},draw:function(){var t,e=this.chart,n=this.getMeta(),i=n.data||[],a=e.chartArea,r=e.canvas,o=0,s=i.length;for(this._showLine&&(t=n.dataset._model.clip,V.canvas.clipArea(e.ctx,{left:!1===t.left?0:a.left-t.left,right:!1===t.right?r.width:a.right+t.right,top:!1===t.top?0:a.top-t.top,bottom:!1===t.bottom?r.height:a.bottom+t.bottom}),n.dataset.draw(),V.canvas.unclipArea(e.ctx));o<s;++o)i[o].draw(a)},setHoverStyle:function(t){var e=t._model,n=t._options,i=V.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Et(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Et(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Et(n.hoverBorderWidth,n.borderWidth),e.radius=Et(n.hoverRadius,n.radius)}}),Yt=V.options.resolve;z._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data,o=r.datasets,s=r.labels;if(a.setAttribute("class",t.id+"-legend"),o.length)for(e=0,n=o[0].data.length;e<n;++e)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return a.outerHTML},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map((function(n,i){var a=t.getDatasetMeta(0),r=a.controller.getStyle(i);return{text:n,fillStyle:r.backgroundColor,strokeStyle:r.borderColor,lineWidth:r.borderWidth,hidden:isNaN(e.datasets[0].data[i])||a.data[i].hidden,index:i}})):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r].hidden=!a.data[r].hidden;o.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}});var Gt=nt.extend({dataElementType:_t.Arc,linkScales:V.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(t){var e,n,i,a=this,r=a.getDataset(),o=a.getMeta(),s=a.chart.options.startAngle||0,l=a._starts=[],u=a._angles=[],d=o.data;for(a._updateRadius(),o.count=a.countVisibleElements(),e=0,n=r.data.length;e<n;e++)l[e]=s,i=a._computeAngle(e),u[e]=i,s+=i;for(e=0,n=d.length;e<n;++e)d[e]._options=a._resolveDataElementOptions(d[e],e),a.updateElement(d[e],e,t)},_updateRadius:function(){var t=this,e=t.chart,n=e.chartArea,i=e.options,a=Math.min(n.right-n.left,n.bottom-n.top);e.outerRadius=Math.max(a/2,0),e.innerRadius=Math.max(i.cutoutPercentage?e.outerRadius/100*i.cutoutPercentage:1,0),e.radiusLength=(e.outerRadius-e.innerRadius)/e.getVisibleDatasetCount(),t.outerRadius=e.outerRadius-e.radiusLength*t.index,t.innerRadius=t.outerRadius-e.radiusLength},updateElement:function(t,e,n){var i=this,a=i.chart,r=i.getDataset(),o=a.options,s=o.animation,l=a.scale,u=a.data.labels,d=l.xCenter,h=l.yCenter,c=o.startAngle,f=t.hidden?0:l.getDistanceFromCenterForValue(r.data[e]),g=i._starts[e],p=g+(t.hidden?0:i._angles[e]),m=s.animateScale?0:l.getDistanceFromCenterForValue(r.data[e]),v=t._options||{};V.extend(t,{_datasetIndex:i.index,_index:e,_scale:l,_model:{backgroundColor:v.backgroundColor,borderColor:v.borderColor,borderWidth:v.borderWidth,borderAlign:v.borderAlign,x:d,y:h,innerRadius:0,outerRadius:n?m:f,startAngle:n&&s.animateRotate?c:g,endAngle:n&&s.animateRotate?c:p,label:V.valueAtIndexOrDefault(u,e,u[e])}}),t.pivot()},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),n=0;return V.each(e.data,(function(e,i){isNaN(t.data[i])||e.hidden||n++})),n},setHoverStyle:function(t){var e=t._model,n=t._options,i=V.getHoverColor,a=V.valueOrDefault;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=a(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=a(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=a(n.hoverBorderWidth,n.borderWidth)},_computeAngle:function(t){var e=this,n=this.getMeta().count,i=e.getDataset(),a=e.getMeta();if(isNaN(i.data[t])||a.data[t].hidden)return 0;var r={chart:e.chart,dataIndex:t,dataset:i,datasetIndex:e.index};return Yt([e.chart.options.elements.arc.angle,2*Math.PI/n],r,t)}});z._set("pie",V.clone(z.doughnut)),z._set("pie",{cutoutPercentage:0});var Xt=Nt,Kt=V.valueOrDefault;z._set("radar",{spanGaps:!1,scale:{type:"radialLinear"},elements:{line:{fill:"start",tension:0}}});var Zt=nt.extend({datasetElementType:_t.Line,dataElementType:_t.Point,linkScales:V.noop,_datasetElementOptions:["backgroundColor","borderWidth","borderColor","borderCapStyle","borderDash","borderDashOffset","borderJoinStyle","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(t){var e,n,i=this,a=i.getMeta(),r=a.dataset,o=a.data||[],s=i.chart.scale,l=i._config;for(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),r._scale=s,r._datasetIndex=i.index,r._children=o,r._loop=!0,r._model=i._resolveDatasetElementOptions(r),r.pivot(),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i=this,a=t.custom||{},r=i.getDataset(),o=i.chart.scale,s=o.getPointPositionForValue(e,r.data[e]),l=i._resolveDataElementOptions(t,e),u=i.getMeta().dataset._model,d=n?o.xCenter:s.x,h=n?o.yCenter:s.y;t._scale=o,t._options=l,t._datasetIndex=i.index,t._index=e,t._model={x:d,y:h,skip:a.skip||isNaN(d)||isNaN(h),radius:l.radius,pointStyle:l.pointStyle,rotation:l.rotation,backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,tension:Kt(a.tension,u?u.tension:0),hitRadius:l.hitRadius}},_resolveDatasetElementOptions:function(){var t=this,e=t._config,n=t.chart.options,i=nt.prototype._resolveDatasetElementOptions.apply(t,arguments);return i.spanGaps=Kt(e.spanGaps,n.spanGaps),i.tension=Kt(e.lineTension,n.elements.line.tension),i},updateBezierControlPoints:function(){var t,e,n,i,a=this.getMeta(),r=this.chart.chartArea,o=a.data||[];function s(t,e,n){return Math.max(Math.min(t,n),e)}for(a.dataset._model.spanGaps&&(o=o.filter((function(t){return!t._model.skip}))),t=0,e=o.length;t<e;++t)n=o[t]._model,i=V.splineCurve(V.previousItem(o,t,!0)._model,n,V.nextItem(o,t,!0)._model,n.tension),n.controlPointPreviousX=s(i.previous.x,r.left,r.right),n.controlPointPreviousY=s(i.previous.y,r.top,r.bottom),n.controlPointNextX=s(i.next.x,r.left,r.right),n.controlPointNextY=s(i.next.y,r.top,r.bottom)},setHoverStyle:function(t){var e=t._model,n=t._options,i=V.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Kt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Kt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Kt(n.hoverBorderWidth,n.borderWidth),e.radius=Kt(n.hoverRadius,n.radius)}});z._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),z._set("global",{datasets:{scatter:{showLine:!1}}});var $t={bar:Dt,bubble:Ft,doughnut:Nt,horizontalBar:Bt,line:Ut,polarArea:Gt,pie:Xt,radar:Zt,scatter:Ut};function Jt(t,e){return t.native?{x:t.x,y:t.y}:V.getRelativePosition(t,e)}function Qt(t,e){var n,i,a,r,o,s,l=t._getSortedVisibleDatasetMetas();for(i=0,r=l.length;i<r;++i)for(a=0,o=(n=l[i].data).length;a<o;++a)(s=n[a])._view.skip||e(s)}function te(t,e){var n=[];return Qt(t,(function(t){t.inRange(e.x,e.y)&&n.push(t)})),n}function ee(t,e,n,i){var a=Number.POSITIVE_INFINITY,r=[];return Qt(t,(function(t){if(!n||t.inRange(e.x,e.y)){var o=t.getCenterPoint(),s=i(e,o);s<a?(r=[t],a=s):s===a&&r.push(t)}})),r}function ne(t){var e=-1!==t.indexOf("x"),n=-1!==t.indexOf("y");return function(t,i){var a=e?Math.abs(t.x-i.x):0,r=n?Math.abs(t.y-i.y):0;return Math.sqrt(Math.pow(a,2)+Math.pow(r,2))}}function ie(t,e,n){var i=Jt(e,t);n.axis=n.axis||"x";var a=ne(n.axis),r=n.intersect?te(t,i):ee(t,i,!1,a),o=[];return r.length?(t._getSortedVisibleDatasetMetas().forEach((function(t){var e=t.data[r[0]._index];e&&!e._view.skip&&o.push(e)})),o):[]}var ae={modes:{single:function(t,e){var n=Jt(e,t),i=[];return Qt(t,(function(t){if(t.inRange(n.x,n.y))return i.push(t),i})),i.slice(0,1)},label:ie,index:ie,dataset:function(t,e,n){var i=Jt(e,t);n.axis=n.axis||"xy";var a=ne(n.axis),r=n.intersect?te(t,i):ee(t,i,!1,a);return r.length>0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ie(t,e,{intersect:!1})},point:function(t,e){return te(t,Jt(e,t))},nearest:function(t,e,n){var i=Jt(e,t);n.axis=n.axis||"xy";var a=ne(n.axis);return ee(t,i,n.intersect,a)},x:function(t,e,n){var i=Jt(e,t),a=[],r=!1;return Qt(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Jt(e,t),a=[],r=!1;return Qt(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},re=V.extend;function oe(t,e){return V.where(t,(function(t){return t.pos===e}))}function se(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function le(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function ue(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-le(o,t,"left","right"),a=e.outerHeight-le(o,t,"top","bottom"),i!==t.w||a!==t.h)return t.w=i,t.h=a,n.horizontal?i!==t.w:a!==t.h}function de(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function he(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;i<a;++i)(o=(r=t[i]).box).update(r.width||e.w,r.height||e.h,de(r.horizontal,e)),ue(e,n,r)&&(l=!0,u.length&&(s=!0)),o.fullWidth||u.push(r);return s&&he(u,e,n)||l}function ce(t,e,n){var i,a,r,o,s=n.padding,l=e.x,u=e.y;for(i=0,a=t.length;i<a;++i)o=(r=t[i]).box,r.horizontal?(o.left=o.fullWidth?s.left:e.left,o.right=o.fullWidth?n.outerWidth-s.right:e.left+e.w,o.top=u,o.bottom=u+o.height,o.width=o.right-o.left,u=o.bottom):(o.left=l,o.right=l+o.width,o.top=e.top,o.bottom=e.top+e.h,o.height=o.bottom-o.top,l=o.right);e.x=l,e.y=u}z._set("global",{layout:{padding:{top:0,right:0,bottom:0,left:0}}});var fe,ge={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw:function(){e.draw.apply(e,arguments)}}]},t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;-1!==n&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var i,a=["fullWidth","position","weight"],r=a.length,o=0;o<r;++o)i=a[o],n.hasOwnProperty(i)&&(e[i]=n[i])},update:function(t,e,n){if(t){var i=t.options.layout||{},a=V.options.toPadding(i.padding),r=e-a.width,o=n-a.height,s=function(t){var e=function(t){var e,n,i,a=[];for(e=0,n=(t||[]).length;e<n;++e)i=t[e],a.push({index:e,box:i,pos:i.position,horizontal:i.isHorizontal(),weight:i.weight});return a}(t),n=se(oe(e,"left"),!0),i=se(oe(e,"right")),a=se(oe(e,"top"),!0),r=se(oe(e,"bottom"));return{leftAndTop:n.concat(a),rightAndBottom:i.concat(r),chartArea:oe(e,"chartArea"),vertical:n.concat(i),horizontal:a.concat(r)}}(t.boxes),l=s.vertical,u=s.horizontal,d=Object.freeze({outerWidth:e,outerHeight:n,padding:a,availableWidth:r,vBoxMaxWidth:r/2/l.length,hBoxMaxHeight:o/2}),h=re({maxPadding:re({},a),w:r,h:o,x:a.left,y:a.top},a);!function(t,e){var n,i,a;for(n=0,i=t.length;n<i;++n)(a=t[n]).width=a.horizontal?a.box.fullWidth&&e.availableWidth:e.vBoxMaxWidth,a.height=a.horizontal&&e.hBoxMaxHeight}(l.concat(u),d),he(l,h,d),he(u,h,d)&&he(l,h,d),function(t){var e=t.maxPadding;function n(n){var i=Math.max(e[n]-t[n],0);return t[n]+=i,i}t.y+=n("top"),t.x+=n("left"),n("right"),n("bottom")}(h),ce(s.leftAndTop,h,d),h.x+=h.w,h.y+=h.h,ce(s.rightAndBottom,h,d),t.chartArea={left:h.left,top:h.top,right:h.left+h.w,bottom:h.top+h.h},V.each(s.chartArea,(function(e){var n=e.box;re(n,t.chartArea),n.update(h.w,h.h)}))}}},pe=(fe=Object.freeze({__proto__:null,default:"@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&fe.default||fe,me="$chartjs",ve="chartjs-size-monitor",be="chartjs-render-monitor",xe="chartjs-render-animation",ye=["animationstart","webkitAnimationStart"],_e={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function ke(t,e){var n=V.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var we=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Me(t,e,n){t.addEventListener(e,n,we)}function Se(t,e,n){t.removeEventListener(e,n,we)}function Ce(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Pe(t){var e=document.createElement("div");return e.className=t||"",e}function Ae(t,e,n){var i,a,r,o,s=t[me]||(t[me]={}),l=s.resizer=function(t){var e=Pe(ve),n=Pe(ve+"-expand"),i=Pe(ve+"-shrink");n.appendChild(Pe()),i.appendChild(Pe()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Me(n,"scroll",a.bind(n,"expand")),Me(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Ce("resize",n)),i&&i.clientWidth<a&&n.canvas&&e(Ce("resize",n))}},r=!1,o=[],function(){o=Array.prototype.slice.call(arguments),a=a||this,r||(r=!0,V.requestAnimFrame.call(window,(function(){r=!1,i.apply(a,o)})))}));!function(t,e){var n=t[me]||(t[me]={}),i=n.renderProxy=function(t){t.animationName===xe&&e()};V.each(ye,(function(e){Me(t,e,i)})),n.reflow=!!t.offsetParent,t.classList.add(be)}(t,(function(){if(s.resizer){var e=t.parentNode;e&&e!==l.parentNode&&e.insertBefore(l,e.firstChild),l._reset()}}))}function De(t){var e=t[me]||{},n=e.resizer;delete e.resizer,function(t){var e=t[me]||{},n=e.renderProxy;n&&(V.each(ye,(function(e){Se(t,e,n)})),delete e.renderProxy),t.classList.remove(be)}(t),n&&n.parentNode&&n.parentNode.removeChild(n)}var Te={disableCSSInjection:!1,_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,_ensureLoaded:function(t){if(!this.disableCSSInjection){var e=t.getRootNode?t.getRootNode():document;!function(t,e){var n=t[me]||(t[me]={});if(!n.containsStyles){n.containsStyles=!0,e="/* Chart.js */\n"+e;var i=document.createElement("style");i.setAttribute("type","text/css"),i.appendChild(document.createTextNode(e)),t.appendChild(i)}}(e.host?e:document.head,pe)}},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var n=t&&t.getContext&&t.getContext("2d");return n&&n.canvas===t?(this._ensureLoaded(t),function(t,e){var n=t.style,i=t.getAttribute("height"),a=t.getAttribute("width");if(t[me]={initial:{height:i,width:a,style:{display:n.display,height:n.height,width:n.width}}},n.display=n.display||"block",null===a||""===a){var r=ke(t,"width");void 0!==r&&(t.width=r)}if(null===i||""===i)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var o=ke(t,"height");void 0!==r&&(t.height=o)}}(t,e),n):null},releaseContext:function(t){var e=t.canvas;if(e[me]){var n=e[me].initial;["height","width"].forEach((function(t){var i=n[t];V.isNullOrUndef(i)?e.removeAttribute(t):e.setAttribute(t,i)})),V.each(n.style||{},(function(t,n){e.style[n]=t})),e.width=e.width,delete e[me]}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=n[me]||(n[me]={});Me(i,e,(a.proxies||(a.proxies={}))[t.id+"_"+e]=function(e){n(function(t,e){var n=_e[t.type]||t.type,i=V.getRelativePosition(t,e);return Ce(n,e,i.x,i.y,t)}(e,t))})}else Ae(i,n,t)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=((n[me]||{}).proxies||{})[t.id+"_"+e];a&&Se(i,e,a)}else De(i)}};V.addEvent=Me,V.removeEvent=Se;var Ie=Te._enabled?Te:{acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}},Fe=V.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},Ie);z._set("global",{plugins:{}});var Le={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach((function(t){-1===e.indexOf(t)&&e.push(t)})),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach((function(t){var n=e.indexOf(t);-1!==n&&e.splice(n,1)})),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,n){var i,a,r,o,s,l=this.descriptors(t),u=l.length;for(i=0;i<u;++i)if("function"==typeof(s=(r=(a=l[i]).plugin)[e])&&((o=[t].concat(n||[])).push(a.options),!1===s.apply(r,o)))return!1;return!0},descriptors:function(t){var e=t.$plugins||(t.$plugins={});if(e.id===this._cacheId)return e.descriptors;var n=[],i=[],a=t&&t.config||{},r=a.options&&a.options.plugins||{};return this._plugins.concat(a.plugins||[]).forEach((function(t){if(-1===n.indexOf(t)){var e=t.id,a=r[e];!1!==a&&(!0===a&&(a=V.clone(z.global.plugins[e])),n.push(t),i.push({plugin:t,options:a||{}}))}})),e.descriptors=i,e.id=this._cacheId,i},_invalidate:function(t){delete t.$plugins}},Oe={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=V.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?V.merge({},[z.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=V.extend(this.defaults[t],e))},addScalesToLayout:function(t){V.each(t.scales,(function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,ge.addBox(t,e)}))}},Re=V.valueOrDefault,ze=V.rtl.getRtlAdapter;z._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:V.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:V.noop,beforeBody:V.noop,beforeLabel:V.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),V.isNullOrUndef(t.value)?n+=t.yLabel:n+=t.value,n},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex).data[t.index]._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:V.noop,afterBody:V.noop,beforeFooter:V.noop,footer:V.noop,afterFooter:V.noop}}});var Ne={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,r=0;for(e=0,n=t.length;e<n;++e){var o=t[e];if(o&&o.hasValue()){var s=o.tooltipPosition();i+=s.x,a+=s.y,++r}}return{x:i/r,y:a/r}},nearest:function(t,e){var n,i,a,r=e.x,o=e.y,s=Number.POSITIVE_INFINITY;for(n=0,i=t.length;n<i;++n){var l=t[n];if(l&&l.hasValue()){var u=l.getCenterPoint(),d=V.distanceBetweenPoints(e,u);d<s&&(s=d,a=l)}}if(a){var h=a.tooltipPosition();r=h.x,o=h.y}return{x:r,y:o}}};function Be(t,e){return e&&(V.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function Ee(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function We(t){var e=z.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:Re(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:Re(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:Re(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:Re(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:Re(t.titleFontStyle,e.defaultFontStyle),titleFontSize:Re(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:Re(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:Re(t.footerFontStyle,e.defaultFontStyle),footerFontSize:Re(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function Ve(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function He(t){return Be([],Ee(t))}var je=X.extend({initialize:function(){this._model=We(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Be(o,Ee(i)),o=Be(o,Ee(a)),o=Be(o,Ee(r))},getBeforeBody:function(){return He(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return V.each(t,(function(t){var r={before:[],lines:[],after:[]};Be(r.before,Ee(i.beforeLabel.call(n,t,e))),Be(r.lines,i.label.call(n,t,e)),Be(r.after,Ee(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return He(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Be(r,Ee(n)),r=Be(r,Ee(i)),r=Be(r,Ee(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=We(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var _=[],k=[];y=Ne[c.position].call(h,p,h._eventPosition);var w=[];for(e=0,n=p.length;e<n;++e)w.push((i=p[e],a=void 0,r=void 0,o=void 0,s=void 0,l=void 0,u=void 0,d=void 0,a=i._xScale,r=i._yScale||i._scale,o=i._index,s=i._datasetIndex,l=i._chart.getDatasetMeta(s).controller,u=l._getIndexScale(),d=l._getValueScale(),{xLabel:a?a.getLabelForIndex(o,s):"",yLabel:r?r.getLabelForIndex(o,s):"",label:u?""+u.getLabelForIndex(o,s):"",value:d?""+d.getLabelForIndex(o,s):"",index:o,datasetIndex:s,x:i._model.x,y:i._model.y}));c.filter&&(w=w.filter((function(t){return c.filter(t,m)}))),c.itemSort&&(w=w.sort((function(t,e){return c.itemSort(t,e,m)}))),V.each(w,(function(t){_.push(c.callbacks.labelColor.call(h,t,h._chart)),k.push(c.callbacks.labelTextColor.call(h,t,h._chart))})),g.title=h.getTitle(w,m),g.beforeBody=h.getBeforeBody(w,m),g.body=h.getBody(w,m),g.afterBody=h.getAfterBody(w,m),g.footer=h.getFooter(w,m),g.x=y.x,g.y=y.y,g.caretPadding=c.caretPadding,g.labelColors=_,g.labelTextColors=k,g.dataPoints=w,x=function(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,r=e.body,o=r.reduce((function(t,e){return t+e.before.length+e.lines.length+e.after.length}),0);o+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,l=e.footer.length,u=e.titleFontSize,d=e.bodyFontSize,h=e.footerFontSize;i+=s*u,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=o*d,i+=o?(o-1)*e.bodySpacing:0,i+=l?e.footerMarginTop:0,i+=l*h,i+=l?(l-1)*e.footerSpacing:0;var c=0,f=function(t){a=Math.max(a,n.measureText(t).width+c)};return n.font=V.fontString(u,e._titleFontStyle,e._titleFontFamily),V.each(e.title,f),n.font=V.fontString(d,e._bodyFontStyle,e._bodyFontFamily),V.each(e.beforeBody.concat(e.afterBody),f),c=e.displayColors?d+2:0,V.each(r,(function(t){V.each(t.before,f),V.each(t.lines,f),V.each(t.after,f)})),c=0,n.font=V.fontString(h,e._footerFontStyle,e._footerFontFamily),V.each(e.footer,f),{width:a+=2*e.xPadding,height:i}}(this,g),b=function(t,e,n,i){var a=t.x,r=t.y,o=t.caretSize,s=t.caretPadding,l=t.cornerRadius,u=n.xAlign,d=n.yAlign,h=o+s,c=l+s;return"right"===u?a-=e.width:"center"===u&&((a-=e.width/2)+e.width>i.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,x,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.y<e.height?h="top":s.y>l.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+p)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+p-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+m)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=ze(e.rtl,e.x,e.width);for(t.x=Ve(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=V.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r<s;++r)n.fillText(o[r],l.x(t.x),t.y+i/2),t.y+=i+a,r+1===s&&(t.y+=e.titleMarginBottom-a)}},drawBody:function(t,e,n){var i,a,r,o,s,l,u,d,h=e.bodyFontSize,c=e.bodySpacing,f=e._bodyAlign,g=e.body,p=e.displayColors,m=0,v=p?Ve(e,"left"):0,b=ze(e.rtl,e.x,e.width),x=function(e){n.fillText(e,b.x(t.x+m),t.y+h/2),t.y+=h+c},y=b.textAlign(f);for(n.textAlign=f,n.textBaseline="middle",n.font=V.fontString(h,e._bodyFontStyle,e._bodyFontFamily),t.x=Ve(e,y),n.fillStyle=e.bodyFontColor,V.each(e.beforeBody,x),m=p&&"right"!==y?"center"===f?h/2+1:h+2:0,s=0,u=g.length;s<u;++s){for(i=g[s],a=e.labelTextColors[s],r=e.labelColors[s],n.fillStyle=a,V.each(i.before,x),l=0,d=(o=i.lines).length;l<d;++l){if(p){var _=b.x(v);n.fillStyle=e.legendColorBackground,n.fillRect(b.leftForLtr(_,h),t.y,h,h),n.lineWidth=1,n.strokeStyle=r.borderColor,n.strokeRect(b.leftForLtr(_,h),t.y,h,h),n.fillStyle=r.backgroundColor,n.fillRect(b.leftForLtr(b.xPlus(_,1),h-2),t.y+1,h-2,h-2),n.fillStyle=a}x(o[l])}V.each(i.after,x)}m=0,V.each(e.afterBody,x),t.y-=c},drawFooter:function(t,e,n){var i,a,r=e.footer,o=r.length;if(o){var s=ze(e.rtl,e.x,e.width);for(t.x=Ve(e,e._footerAlign),t.y+=e.footerMarginTop,n.textAlign=s.textAlign(e._footerAlign),n.textBaseline="middle",i=e.footerFontSize,n.fillStyle=e.footerFontColor,n.font=V.fontString(i,e._footerFontStyle,e._footerFontFamily),a=0;a<o;++a)n.fillText(r[a],s.x(t.x),t.y+i/2),t.y+=i+e.footerSpacing}},drawBackground:function(t,e,n,i){n.fillStyle=e.backgroundColor,n.strokeStyle=e.borderColor,n.lineWidth=e.borderWidth;var a=e.xAlign,r=e.yAlign,o=t.x,s=t.y,l=i.width,u=i.height,d=e.cornerRadius;n.beginPath(),n.moveTo(o+d,s),"top"===r&&this.drawCaret(t,i),n.lineTo(o+l-d,s),n.quadraticCurveTo(o+l,s,o+l,s+d),"center"===r&&"right"===a&&this.drawCaret(t,i),n.lineTo(o+l,s+u-d),n.quadraticCurveTo(o+l,s+u,o+l-d,s+u),"bottom"===r&&this.drawCaret(t,i),n.lineTo(o+d,s+u),n.quadraticCurveTo(o,s+u,o,s+u-d),"center"===r&&"left"===a&&this.drawCaret(t,i),n.lineTo(o,s+d),n.quadraticCurveTo(o,s,o+d,s),n.closePath(),n.fill(),e.borderWidth>0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,V.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),V.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!V.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),qe=Ne,Ue=je;Ue.positioners=qe;var Ye=V.valueOrDefault;function Ge(){return V.merge({},[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a<s;++a)o=n[t][a],r=Ye(o.type,"xAxes"===t?"category":"linear"),a>=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?V.merge(e[t][a],[Oe.getScaleDefaults(r),o]):V.merge(e[t][a],o)}else V._merger(t,e,n,i)}})}function Xe(){return V.merge({},[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||{},r=n[t];"scales"===t?e[t]=Ge(a,r):"scale"===t?e[t]=V.merge(a,[Oe.getScaleDefaults(r.type),r]):V._merger(t,e,n,i)}})}function Ke(t){var e=t.options;V.each(t.scales,(function(e){ge.removeBox(t,e)})),e=Xe(z.global,z[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function Ze(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(V.findIndex(t,a)>=0);return i}function $e(t){return"top"===t||"bottom"===t}function Je(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}z._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var Qe=function(t,e){return this.construct(t,e),this};V.extend(Qe.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||{}).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Xe(z.global,z[t.type],t.options||{}),t}(e);var i=Fe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=V.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,Qe.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),V.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return V.canvas.clear(this),this},stop:function(){return $.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(V.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:V.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",V.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;V.each(e.xAxes,(function(t,n){t.id||(t.id=Ze(e.xAxes,"x-axis-",n))})),V.each(e.yAxes,(function(t,n){t.id||(t.id=Ze(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),V.each(i,(function(e){var i=e.options,r=i.id,o=Ye(i.type,e.dtype);$e(i.position)!==$e(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Oe.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),V.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Oe.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t<e;t++){var r=a[t],o=n.getDatasetMeta(t),s=r.type||n.config.type;if(o.type&&o.type!==s&&(n.destroyDatasetMeta(t),o=n.getDatasetMeta(t)),o.type=s,o.order=r.order||0,o.index=t,o.controller)o.controller.updateIndex(t),o.controller.linkScales();else{var l=$t[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(n,t),i.push(o.controller)}}return i},resetElements:function(){var t=this;V.each(t.data.datasets,(function(e,n){t.getDatasetMeta(n).controller.reset()}),t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t){var e,n,i=this;if(t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]}),Ke(i),Le._invalidate(i),!1!==Le.notify(i,"beforeUpdate")){i.tooltip._data=i.data;var a=i.buildOrUpdateControllers();for(e=0,n=i.data.datasets.length;e<n;e++)i.getDatasetMeta(e).controller.buildOrUpdateElements();i.updateLayout(),i.options.animation&&i.options.animation.duration&&V.each(a,(function(t){t.reset()})),i.updateDatasets(),i.tooltip.initialize(),i.lastActive=[],Le.notify(i,"afterUpdate"),i._layers.sort(Je("z","_idx")),i._bufferedRender?i._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:i.render(t)}},updateLayout:function(){var t=this;!1!==Le.notify(t,"beforeLayout")&&(ge.update(this,this.width,this.height),t._layers=[],V.each(t.boxes,(function(e){e._configure&&e._configure(),t._layers.push.apply(t._layers,e._layers())}),t),t._layers.forEach((function(t,e){t._idx=e})),Le.notify(t,"afterScaleUpdate"),Le.notify(t,"afterLayout"))},updateDatasets:function(){if(!1!==Le.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t<e;++t)this.updateDataset(t);Le.notify(this,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this.getDatasetMeta(t),n={meta:e,index:t};!1!==Le.notify(this,"beforeDatasetUpdate",[n])&&(e.controller._update(),Le.notify(this,"afterDatasetUpdate",[n]))},render:function(t){var e=this;t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]});var n=e.options.animation,i=Ye(t.duration,n&&n.duration),a=t.lazy;if(!1!==Le.notify(e,"beforeRender")){var r=function(t){Le.notify(e,"afterRender"),V.callback(n&&n.onComplete,[t],e)};if(n&&i){var o=new Z({numSteps:i/16.66,easing:t.easing||n.easing,render:function(t,e){var n=V.easing.effects[e.easing],i=e.currentStep,a=i/e.numSteps;t.draw(n(a),a,i)},onAnimationProgress:n.onProgress,onAnimationComplete:r});$.addAnimation(e,o,i,a)}else e.draw(),r(new Z({numSteps:0,chart:e}));return e}},draw:function(t){var e,n,i=this;if(i.clear(),V.isNullOrUndef(t)&&(t=1),i.transition(t),!(i.width<=0||i.height<=0)&&!1!==Le.notify(i,"beforeDraw",[t])){for(n=i._layers,e=0;e<n.length&&n[e].z<=0;++e)n[e].draw(i.chartArea);for(i.drawDatasets(t);e<n.length;++e)n[e].draw(i.chartArea);i._drawTooltip(t),Le.notify(i,"afterDraw",[t])}},transition:function(t){for(var e=0,n=(this.data.datasets||[]).length;e<n;++e)this.isDatasetVisible(e)&&this.getDatasetMeta(e).controller.transition(t);this.tooltip.transition(t)},_getSortedDatasetMetas:function(t){var e,n,i=[];for(e=0,n=(this.data.datasets||[]).length;e<n;++e)t&&!this.isDatasetVisible(e)||i.push(this.getDatasetMeta(e));return i.sort(Je("order","index")),i},_getSortedVisibleDatasetMetas:function(){return this._getSortedDatasetMetas(!0)},drawDatasets:function(t){var e,n;if(!1!==Le.notify(this,"beforeDatasetsDraw",[t])){for(n=(e=this._getSortedVisibleDatasetMetas()).length-1;n>=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return ae.modes.single(this,t)},getElementsAtEvent:function(t){return ae.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return ae.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=ae.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return ae.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e<n;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroyDatasetMeta:function(t){var e=this.id,n=this.data.datasets[t],i=n._meta&&n._meta[e];i&&(i.controller.destroy(),delete n._meta[e])},destroy:function(){var t,e,n=this,i=n.canvas;for(n.stop(),t=0,e=n.data.datasets.length;t<e;++t)n.destroyDatasetMeta(t);i&&(n.unbindEvents(),V.canvas.clear(n),Fe.releaseContext(n.ctx),n.canvas=null,n.ctx=null),Le.notify(n,"destroy"),delete Qe.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var t=this;t.tooltip=new Ue({_chart:t,_chartInstance:t,_data:t.data,_options:t.options.tooltips},t)},bindEvents:function(){var t=this,e=t._listeners={},n=function(){t.eventHandler.apply(t,arguments)};V.each(t.options.events,(function(i){Fe.addEventListener(t,i,n),e[i]=n})),t.options.responsive&&(n=function(){t.resize()},Fe.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,V.each(e,(function(e,n){Fe.removeEventListener(t,n,e)})))},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"set":"remove";for(a=0,r=t.length;a<r;++a)(i=t[a])&&this.getDatasetMeta(i._datasetIndex).controller[o+"HoverStyle"](i);"dataset"===e&&this.getDatasetMeta(t[0]._datasetIndex).controller["_"+o+"DatasetHoverStyle"]()},eventHandler:function(t){var e=this,n=e.tooltip;if(!1!==Le.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);n&&(i=n._start?n.handleEvent(t):i|n.handleEvent(t)),Le.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):i&&!e.animating&&(e.stop(),e.render({duration:e.options.hover.animationDuration,lazy:!0})),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e,n=this,i=n.options||{},a=i.hover;return n.lastActive=n.lastActive||[],"mouseout"===t.type?n.active=[]:n.active=n.getElementsAtEventForMode(t,a.mode,a),V.callback(i.onHover||i.hover.onHover,[t.native,n.active],n),"mouseup"!==t.type&&"click"!==t.type||i.onClick&&i.onClick.call(n,t.native,n.active),n.lastActive.length&&n.updateHoverStyle(n.lastActive,a.mode,!1),n.active.length&&a.mode&&n.updateHoverStyle(n.active,a.mode,!0),e=!V.arrayEquals(n.active,n.lastActive),n.lastActive=n.active,e}}),Qe.instances={};var tn=Qe;Qe.Controller=Qe,Qe.types={},V.configMerge=Xe,V.scaleMerge=Ge;function en(){throw new Error("This method is not implemented: either no adapter can be found or an incomplete integration was provided.")}function nn(t){this.options=t||{}}V.extend(nn.prototype,{formats:en,parse:en,format:en,add:en,diff:en,startOf:en,endOf:en,_create:function(t){return t}}),nn.override=function(t){V.extend(nn.prototype,t)};var an={_date:nn},rn={formatters:{values:function(t){return V.isArray(t)?t:""+t},linear:function(t,e,n){var i=n.length>3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=V.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=V.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(V.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},on=V.isArray,sn=V.isNullOrUndef,ln=V.valueOrDefault,un=V.valueAtIndexOrDefault;function dn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=r<e?i:-i)<s-1e-6||o>l+1e-6)))return o}function hn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,p,m,v=n.length,b=[],x=[],y=[];for(a=0;a<v;++a){if(s=n[a].label,l=n[a].major?e.major:e.minor,t.font=u=l.string,d=i[u]=i[u]||{data:{},gc:[]},h=l.lineHeight,c=f=0,sn(s)||on(s)){if(on(s))for(r=0,o=s.length;r<o;++r)g=s[r],sn(g)||on(g)||(c=V.measureText(t,d.data,d.gc,c,g),f+=h)}else c=V.measureText(t,d.data,d.gc,c,s),f=h;b.push(c),x.push(f),y.push(h/2)}function _(t){return{width:b[t]||0,height:x[t]||0,offset:y[t]||0}}return function(t,e){V.each(t,(function(t){var n,i=t.gc,a=i.length/2;if(a>e){for(n=0;n<a;++n)delete t.data[i[n]];i.splice(0,a)}}))}(i,v),p=b.indexOf(Math.max.apply(null,b)),m=x.indexOf(Math.max.apply(null,x)),{first:_(0),last:_(v-1),widest:_(p),highest:_(m)}}function cn(t){return t.drawTicks?t.tickMarkLength:0}function fn(t){var e,n;return t.display?(e=V.options._parseFont(t),n=V.options.toPadding(t.padding),e.lineHeight+n.height):0}function gn(t,e){return V.extend(V.options._parseFont({fontFamily:ln(e.fontFamily,t.fontFamily),fontSize:ln(e.fontSize,t.fontSize),fontStyle:ln(e.fontStyle,t.fontStyle),lineHeight:ln(e.lineHeight,t.lineHeight)}),{color:V.options.resolve([e.fontColor,t.fontColor,z.global.defaultFontColor])})}function pn(t){var e=gn(t,t.minor);return{minor:e,major:t.major.enabled?gn(t,t.major):e}}function mn(t){var e,n,i,a=[];for(n=0,i=t.length;n<i;++n)void 0!==(e=t[n])._index&&a.push(e);return a}function vn(t,e,n,i){var a,r,o,s,l=ln(n,0),u=Math.min(ln(i,t.length),t.length),d=0;for(e=Math.ceil(e),i&&(e=(a=i-n)/Math.floor(a/e)),s=l;s<0;)d++,s=Math.round(l+d*e);for(r=Math.max(l,0);r<u;r++)o=t[r],r===s?(o._index=r,d++,s=Math.round(l+d*e)):delete o.label}z._set("scale",{display:!0,position:"left",offset:!1,gridLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:rn.formatters.values,minor:{},major:{}}});var bn=X.extend({zeroLineIndex:0,getPadding:function(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}},getTicks:function(){return this._ticks},_getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]},mergeTicksOptions:function(){},beforeUpdate:function(){V.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var i,a,r,o,s,l=this,u=l.options.ticks,d=u.sampleSize;if(l.beforeUpdate(),l.maxWidth=t,l.maxHeight=e,l.margins=V.extend({left:0,right:0,top:0,bottom:0},n),l._ticks=null,l.ticks=null,l._labelSizes=null,l._maxLabelLines=0,l.longestLabelWidth=0,l.longestTextCache=l.longestTextCache||{},l._gridLineItems=null,l._labelItems=null,l.beforeSetDimensions(),l.setDimensions(),l.afterSetDimensions(),l.beforeDataLimits(),l.determineDataLimits(),l.afterDataLimits(),l.beforeBuildTicks(),o=l.buildTicks()||[],(!(o=l.afterBuildTicks(o)||o)||!o.length)&&l.ticks)for(o=[],i=0,a=l.ticks.length;i<a;++i)o.push({value:l.ticks[i],major:!1});return l._ticks=o,s=d<o.length,r=l._convertTicksToLabels(s?function(t,e){for(var n=[],i=t.length/e,a=0,r=t.length;a<r;a+=i)n.push(t[Math.floor(a)]);return n}(o,d):o),l._configure(),l.beforeCalculateTickRotation(),l.calculateTickRotation(),l.afterCalculateTickRotation(),l.beforeFit(),l.fit(),l.afterFit(),l._ticksToDraw=u.display&&(u.autoSkip||"auto"===u.source)?l._autoSkip(o):o,s&&(r=l._convertTicksToLabels(l._ticksToDraw)),l.ticks=r,l.afterUpdate(),l.minSize},_configure:function(){var t,e,n=this,i=n.options.ticks.reverse;n.isHorizontal()?(t=n.left,e=n.right):(t=n.top,e=n.bottom,i=!i),n._startPixel=t,n._endPixel=e,n._reversePixels=i,n._length=e-t},afterUpdate:function(){V.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){V.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){V.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){V.callback(this.options.beforeDataLimits,[this])},determineDataLimits:V.noop,afterDataLimits:function(){V.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){V.callback(this.options.beforeBuildTicks,[this])},buildTicks:V.noop,afterBuildTicks:function(t){var e=this;return on(t)&&t.length?V.callback(e.options.afterBuildTicks,[e,t]):(e.ticks=V.callback(e.options.afterBuildTicks,[e,e.ticks])||e.ticks,t)},beforeTickToLabelConversion:function(){V.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this.options.ticks;this.ticks=this.ticks.map(t.userCallback||t.callback,this)},afterTickToLabelConversion:function(){V.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){V.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t,e,n,i,a,r,o,s=this,l=s.options,u=l.ticks,d=s.getTicks().length,h=u.minRotation||0,c=u.maxRotation,f=h;!s._isVisible()||!u.display||h>=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-cn(l.gridLines)-u.padding-fn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=V.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){V.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){V.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=cn(o)+fn(r)),u?s&&(e.height=cn(o)+fn(r)):e.height=t.maxHeight,a.display&&s){var d=pn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,p=h.highest,m=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,x=V.toRadians(t.labelRotation),y=Math.cos(x),_=Math.sin(x),k=_*g.width+y*(p.height-(b?p.offset:0))+(b?0:m);e.height=Math.min(t.maxHeight,e.height+k+v);var w,M,S=t.getPixelForTick(0)-t.left,C=t.right-t.getPixelForTick(t.getTicks().length-1);b?(w=l?y*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):y*f.width+_*f.offset):(w=c.width/2,M=f.width/2),t.paddingLeft=Math.max((w-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-C)*t.width/(t.width-C),0)+3}else{var P=a.mirror?0:g.width+v+m;e.width=Math.min(t.maxWidth,e.width+P),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){V.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(sn(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;n<i;++n)t[n].label=e[n];return e},_getLabelSizes:function(){var t=this,e=t._labelSizes;return e||(t._labelSizes=e=hn(t.ctx,pn(t.options.ticks),t.getTicks(),t.longestTextCache),t.longestLabelWidth=e.widest.width),e},_parseValue:function(t){var e,n,i,a;return on(t)?(e=+this.getRightValue(t[0]),n=+this.getRightValue(t[1]),i=Math.min(e,n),a=Math.max(e,n)):(e=void 0,n=t=+this.getRightValue(t),i=t,a=t),{min:i,max:a,start:e,end:n}},_getScaleLabel:function(t){var e=this._parseValue(t);return void 0!==e.start?"["+e.start+", "+e.end+"]":+this.getRightValue(t)},getLabelForIndex:V.noop,getPixelForValue:V.noop,getValueForPixel:V.noop,getPixelForTick:function(t){var e=this.options.offset,n=this._ticks.length,i=1/Math.max(n-(e?0:1),1);return t<0||t>n-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;e<n;e++)t[e].major&&i.push(e);return i}(t):[],u=l.length,d=l[0],h=l[u-1];if(u>s)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;i<t.length;i++)a=t[i],i===o?(a._index=i,o=e[++r*n]):delete a.label}(t,l,u/s),mn(t);if(i=function(t,e,n,i){var a,r,o,s,l=function(t){var e,n,i=t.length;if(i<2)return!1;for(n=t[0],e=1;e<i;++e)if(t[e]-t[e-1]!==n)return!1;return n}(t),u=(e.length-1)/i;if(!l)return Math.max(u,1);for(o=0,s=(a=V.math._factorize(l)).length-1;o<s;o++)if((r=a[o])>u)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e<n;e++)vn(t,i,l[e],l[e+1]);return a=u>1?(h-d)/(u-1):null,vn(t,i,V.isNullOrUndef(a)?0:d-a,d),vn(t,i,h,V.isNullOrUndef(a)?t.length:h+a),mn(t)}return vn(t,i),mn(t)},_tickSize:function(){var t=this.options.ticks,e=V.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i<o*n?s/n:o/i},_isVisible:function(){var t,e,n,i=this.chart,a=this.options.display;if("auto"!==a)return!!a;for(t=0,e=i.data.datasets.length;t<e;++t)if(i.isDatasetVisible(t)&&((n=i.getDatasetMeta(t)).xAxisID===this.id||n.yAxisID===this.id))return!0;return!1},_computeGridLineItems:function(t){var e,n,i,a,r,o,s,l,u,d,h,c,f,g,p,m,v,b=this,x=b.chart,y=b.options,_=y.gridLines,k=y.position,w=_.offsetGridLines,M=b.isHorizontal(),S=b._ticksToDraw,C=S.length+(w?1:0),P=cn(_),A=[],D=_.drawBorder?un(_.lineWidth,0,0):0,T=D/2,I=V._alignPixel,F=function(t){return I(x,t,D)};for("top"===k?(e=F(b.bottom),s=b.bottom-P,u=e-T,h=F(t.top)+T,f=t.bottom):"bottom"===k?(e=F(b.top),h=t.top,f=F(t.bottom)-T,s=e+T,u=b.top+P):"left"===k?(e=F(b.right),o=b.right-P,l=e-T,d=F(t.left)+T,c=t.right):(e=F(b.left),d=t.left,c=F(t.right)-T,o=e+T,l=b.left+P),n=0;n<C;++n)i=S[n]||{},sn(i.label)&&n<S.length||(n===b.zeroLineIndex&&y.offset===w?(g=_.zeroLineWidth,p=_.zeroLineColor,m=_.zeroLineBorderDash||[],v=_.zeroLineBorderDashOffset||0):(g=un(_.lineWidth,n,1),p=un(_.color,n,"rgba(0,0,0,0.1)"),m=_.borderDash||[],v=_.borderDashOffset||0),void 0!==(a=dn(b,i._index||n,w))&&(r=I(x,a,g),M?o=l=d=c=r:s=u=h=f=r,A.push({tx1:o,ty1:s,tx2:l,ty2:u,x1:d,y1:h,x2:c,y2:f,width:g,color:p,borderDash:m,borderDashOffset:v})));return A.ticksLength=C,A.borderValue=e,A},_computeLabelItems:function(){var t,e,n,i,a,r,o,s,l,u,d,h,c=this,f=c.options,g=f.ticks,p=f.position,m=g.mirror,v=c.isHorizontal(),b=c._ticksToDraw,x=pn(g),y=g.padding,_=cn(f.gridLines),k=-V.toRadians(c.labelRotation),w=[];for("top"===p?(r=c.bottom-_-y,o=k?"left":"center"):"bottom"===p?(r=c.top+_+y,o=k?"right":"center"):"left"===p?(a=c.right-(m?0:_)-y,o=m?"left":"right"):(a=c.left+(m?0:_)+y,o=m?"right":"left"),t=0,e=b.length;t<e;++t)i=(n=b[t]).label,sn(i)||(s=c.getPixelForTick(n._index||t)+g.labelOffset,u=(l=n.major?x.major:x.minor).lineHeight,d=on(i)?i.length:1,v?(a=s,h="top"===p?((k?1:.5)-d)*u:(k?0:.5)*u):(r=s,h=(1-d)*u/2),w.push({x:a,y:r,rotation:k,label:i,font:l,textOffset:h,textAlign:o}));return w},_drawGrid:function(t){var e=this,n=e.options.gridLines;if(n.display){var i,a,r,o,s,l=e.ctx,u=e.chart,d=V._alignPixel,h=n.drawBorder?un(n.lineWidth,0,0):0,c=e._gridLineItems||(e._gridLineItems=e._computeGridLineItems(t));for(r=0,o=c.length;r<o;++r)i=(s=c[r]).width,a=s.color,i&&a&&(l.save(),l.lineWidth=i,l.strokeStyle=a,l.setLineDash&&(l.setLineDash(s.borderDash),l.lineDashOffset=s.borderDashOffset),l.beginPath(),n.drawTicks&&(l.moveTo(s.tx1,s.ty1),l.lineTo(s.tx2,s.ty2)),n.drawOnChartArea&&(l.moveTo(s.x1,s.y1),l.lineTo(s.x2,s.y2)),l.stroke(),l.restore());if(h){var f,g,p,m,v=h,b=un(n.lineWidth,c.ticksLength-1,1),x=c.borderValue;e.isHorizontal()?(f=d(u,e.left,v)-v/2,g=d(u,e.right,b)+b/2,p=m=x):(p=d(u,e.top,v)-v/2,m=d(u,e.bottom,b)+b/2,f=g=x),l.lineWidth=h,l.strokeStyle=un(n.color,0),l.beginPath(),l.moveTo(f,p),l.lineTo(g,m),l.stroke()}}},_drawLabels:function(){var t=this;if(t.options.ticks.display){var e,n,i,a,r,o,s,l,u=t.ctx,d=t._labelItems||(t._labelItems=t._computeLabelItems());for(e=0,i=d.length;e<i;++e){if(o=(r=d[e]).font,u.save(),u.translate(r.x,r.y),u.rotate(r.rotation),u.font=o.string,u.fillStyle=o.color,u.textBaseline="middle",u.textAlign=r.textAlign,s=r.label,l=r.textOffset,on(s))for(n=0,a=s.length;n<a;++n)u.fillText(""+s[n],0,l),l+=o.lineHeight;else u.fillText(s,0,l);u.restore()}}},_drawTitle:function(){var t=this,e=t.ctx,n=t.options,i=n.scaleLabel;if(i.display){var a,r,o=ln(i.fontColor,z.global.defaultFontColor),s=V.options._parseFont(i),l=V.options.toPadding(i.padding),u=s.lineHeight/2,d=n.position,h=0;if(t.isHorizontal())a=t.left+t.width/2,r="bottom"===d?t.bottom-u-l.bottom:t.top+u+l.top;else{var c="left"===d;a=c?t.left+u+l.top:t.right-u-l.top,r=t.top+t.height/2,h=c?-.5*Math.PI:.5*Math.PI}e.save(),e.translate(a,r),e.rotate(h),e.textAlign="center",e.textBaseline="middle",e.fillStyle=o,e.font=s.string,e.fillText(i.labelString,0,0),e.restore()}},draw:function(t){this._isVisible()&&(this._drawGrid(t),this._drawTitle(),this._drawLabels())},_layers:function(){var t=this,e=t.options,n=e.ticks&&e.ticks.z||0,i=e.gridLines&&e.gridLines.z||0;return t._isVisible()&&n!==i&&t.draw===t._draw?[{z:i,draw:function(){t._drawGrid.apply(t,arguments),t._drawTitle.apply(t,arguments)}},{z:n,draw:function(){t._drawLabels.apply(t,arguments)}}]:[{z:n,draw:function(){t.draw.apply(t,arguments)}}]},_getMatchingVisibleMetas:function(t){var e=this,n=e.isHorizontal();return e.chart._getSortedVisibleDatasetMetas().filter((function(i){return(!t||i.type===t)&&(n?i.xAxisID===e.id:i.yAxisID===e.id)}))}});bn.prototype._draw=bn.prototype.draw;var xn=bn,yn=V.isNullOrUndef,_n=xn.extend({determineDataLimits:function(){var t,e=this,n=e._getLabels(),i=e.options.ticks,a=i.min,r=i.max,o=0,s=n.length-1;void 0!==a&&(t=n.indexOf(a))>=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;xn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return yn(e)||yn(n)||(t=o.chart.data.datasets[n].data[e]),yn(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=V.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),kn={position:"bottom"};_n._defaults=kn;var wn=V.noop,Mn=V.isNullOrUndef;var Sn=xn.extend({getRightValue:function(t){return"string"==typeof t?+t:xn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=V.sign(t.min),i=V.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:wn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:V.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=V.niceNum((g-f)/u/l)*l;if(p<1e-14&&Mn(d)&&Mn(h))return[f,g];(r=Math.ceil(g/p)-Math.floor(f/p))>u&&(p=V.niceNum(r*p/u/l)*l),s||Mn(c)?n=Math.pow(10,V._decimalPlaces(p)):(n=Math.pow(10,c),p=Math.ceil(p*n)/n),i=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!Mn(d)&&V.almostWhole(d/p,p/1e3)&&(i=d),!Mn(h)&&V.almostWhole(h/p,p/1e3)&&(a=h)),r=(a-i)/p,r=V.almostEquals(r,Math.round(r),p/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Mn(d)?i:d);for(var m=1;m<r;++m)o.push(Math.round((i+m*p)*n)/n);return o.push(Mn(h)?a:h),o}(i,t);t.handleDirectionalChanges(),t.max=V.max(a),t.min=V.min(a),e.reverse?(a.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var t=this;t.ticksAsNumbers=t.ticks.slice(),t.zeroLineIndex=t.ticks.indexOf(0),xn.prototype.convertTicksToLabels.call(t)},_configure:function(){var t,e=this,n=e.getTicks(),i=e.min,a=e.max;xn.prototype._configure.call(e),e.options.offset&&n.length&&(i-=t=(a-i)/Math.max(n.length-1,1)/2,a+=t),e._startValue=i,e._endValue=a,e._valueRange=a-i}}),Cn={position:"left",ticks:{callback:rn.formatters.linear}};function Pn(t,e,n,i){var a,r,o=t.options,s=function(t,e,n){var i=[n.type,void 0===e&&void 0===n.stack?n.index:"",n.stack].join(".");return void 0===t[i]&&(t[i]={pos:[],neg:[]}),t[i]}(e,o.stacked,n),l=s.pos,u=s.neg,d=i.length;for(a=0;a<d;++a)r=t._parseValue(i[a]),isNaN(r.min)||isNaN(r.max)||n.data[a].hidden||(l[a]=l[a]||0,u[a]=u[a]||0,o.relativePoints?l[a]=100:r.min<0||r.max<0?u[a]+=r.min:l[a]+=r.max)}function An(t,e,n){var i,a,r=n.length;for(i=0;i<r;++i)a=t._parseValue(n[i]),isNaN(a.min)||isNaN(a.max)||e.data[i].hidden||(t.min=Math.min(t.min,a.min),t.max=Math.max(t.max,a.max))}var Dn=Sn.extend({determineDataLimits:function(){var t,e,n,i,a=this,r=a.options,o=a.chart.data.datasets,s=a._getMatchingVisibleMetas(),l=r.stacked,u={},d=s.length;if(a.min=Number.POSITIVE_INFINITY,a.max=Number.NEGATIVE_INFINITY,void 0===l)for(t=0;!l&&t<d;++t)l=void 0!==(e=s[t]).stack;for(t=0;t<d;++t)n=o[(e=s[t]).index].data,l?Pn(a,u,e,n):An(a,e,n);V.each(u,(function(t){i=t.pos.concat(t.neg),a.min=Math.min(a.min,V.min(i)),a.max=Math.max(a.max,V.max(i))})),a.min=V.isFinite(a.min)&&!isNaN(a.min)?a.min:0,a.max=V.isFinite(a.max)&&!isNaN(a.max)?a.max:1,a.handleTickRangeOptions()},_computeTickLimit:function(){var t;return this.isHorizontal()?Math.ceil(this.width/40):(t=V.options._parseFont(this.options.ticks),Math.ceil(this.height/t.lineHeight))},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return this._getScaleLabel(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){return this.getPixelForDecimal((+this.getRightValue(t)-this._startValue)/this._valueRange)},getValueForPixel:function(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange},getPixelForTick:function(t){var e=this.ticksAsNumbers;return t<0||t>e.length-1?null:this.getPixelForValue(e[t])}}),Tn=Cn;Dn._defaults=Tn;var In=V.valueOrDefault,Fn=V.math.log10;var Ln={position:"left",ticks:{callback:rn.formatters.logarithmic}};function On(t,e){return V.isFinite(t)&&t>=0?t:e}var Rn=xn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t<u.length;t++)if(e=l.getDatasetMeta(t),l.isDatasetVisible(t)&&h(e)&&void 0!==e.stack){c=!0;break}if(s.stacked||c){var f={};for(t=0;t<u.length;t++){var g=[(e=l.getDatasetMeta(t)).type,void 0===s.stacked&&void 0===e.stack?t:"",e.stack].join(".");if(l.isDatasetVisible(t)&&h(e))for(void 0===f[g]&&(f[g]=[]),a=0,r=(i=u[t].data).length;a<r;a++){var p=f[g];n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(p[a]=p[a]||0,p[a]+=n.max)}}V.each(f,(function(t){if(t.length>0){var e=V.min(t),n=V.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t<u.length;t++)if(e=l.getDatasetMeta(t),l.isDatasetVisible(t)&&h(e))for(a=0,r=(i=u[t].data).length;a<r;a++)n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(o.min=Math.min(n.min,o.min),o.max=Math.max(n.max,o.max),0!==n.min&&(o.minNotZero=Math.min(n.min,o.minNotZero)));o.min=V.isFinite(o.min)?o.min:null,o.max=V.isFinite(o.max)?o.max:null,o.minNotZero=V.isFinite(o.minNotZero)?o.minNotZero:null,this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;t.min=On(e.min,t.min),t.max=On(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(Fn(t.min))-1),t.max=Math.pow(10,Math.floor(Fn(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(Fn(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(Fn(t.min))+1):10),null===t.minNotZero&&(t.min>0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(Fn(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:On(e.min),max:On(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=In(t.min,Math.pow(10,Math.floor(Fn(e.min)))),o=Math.floor(Fn(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(Fn(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(Fn(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(n<o||n===o&&i<s);var u=In(t.max,r);return a.push(u),a}(i,t);t.max=V.max(a),t.min=V.min(a),e.reverse?(n=!n,t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),n&&a.reverse()},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),xn.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return this._getScaleLabel(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){var e=this.tickValues;return t<0||t>e.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(Fn(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;xn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=In(t.options.ticks.fontSize,z.global.defaultFontSize)/t._length),t._startValue=Fn(e),t._valueOffset=n,t._valueRange=(Fn(t.max)-Fn(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(Fn(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),zn=Ln;Rn._defaults=zn;var Nn=V.valueOrDefault,Bn=V.valueAtIndexOrDefault,En=V.options.resolve,Wn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:rn.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Vn(t){var e=t.ticks;return e.display&&t.display?Nn(e.fontSize,z.global.defaultFontSize)+2*e.backdropPaddingY:0}function Hn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:t<i||t>a?{start:e-n,end:e}:{start:e,end:e+n}}function jn(t){return 0===t||180===t?"center":t<180?"left":"right"}function qn(t,e,n,i){var a,r,o=n.y+i/2;if(V.isArray(e))for(a=0,r=e.length;a<r;++a)t.fillText(e[a],n.x,o),o+=i;else t.fillText(e,n.x,o)}function Un(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function Yn(t){return V.isNumber(t)?t:0}var Gn=Sn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Vn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;V.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);V.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Vn(this.options))},convertTicksToLabels:function(){var t=this;Sn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=V.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=V.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;e<d;e++){i=t.getPointPosition(e,t.drawingArea+5),s=t.ctx,l=a.lineHeight,u=t.pointLabels[e],n=V.isArray(u)?{w:V.longestText(s,s.font,u),h:u.length*l}:{w:s.measureText(u).width,h:l},t._pointLabelSizes[e]=n;var h=t.getIndexAngle(e),c=V.toDegrees(h)%360,f=Hn(c,i.x,n.w,0,180),g=Hn(c,i.y,n.h,90,270);f.start<r.l&&(r.l=f.start,o.l=h),f.end>r.r&&(r.r=f.end,o.r=h),g.start<r.t&&(r.t=g.start,o.t=h),g.end>r.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Yn(a),r=Yn(r),o=Yn(o),s=Yn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(V.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Nn(s.lineWidth,o.lineWidth),u=Nn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Vn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=V.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=Bn(i.fontColor,s,z.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=V.toDegrees(h);e.textAlign=jn(c),Un(c,t._pointLabelSizes[s],u),qn(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&V.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=Bn(e.color,i-1),u=Bn(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d<s;d++)a=t.getPointPosition(d,n),r.lineTo(a.x,a.y)}r.closePath(),r.stroke(),r.restore()}}(i,o,e,n))})),s.display&&l&&u){for(a.save(),a.lineWidth=l,a.strokeStyle=u,a.setLineDash&&(a.setLineDash(En([s.borderDash,o.borderDash,[]])),a.lineDashOffset=En([s.borderDashOffset,o.borderDashOffset,0])),t=i.chart.data.labels.length-1;t>=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=V.options._parseFont(n),s=Nn(n.fontColor,z.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",V.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:V.noop}),Xn=Wn;Gn._defaults=Xn;var Kn=V._deprecated,Zn=V.options.resolve,$n=V.valueOrDefault,Jn=Number.MIN_SAFE_INTEGER||-9007199254740991,Qn=Number.MAX_SAFE_INTEGER||9007199254740991,ti={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ei=Object.keys(ti);function ni(t,e){return t-e}function ii(t){return V.valueOrDefault(t.time.min,t.ticks.min)}function ai(t){return V.valueOrDefault(t.time.max,t.ticks.max)}function ri(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]<n)o=i+1;else{if(!(a[e]>n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function oi(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),V.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),V.isFinite(o)||(o=n.parse(o))),o)}function si(t,e){if(V.isNullOrUndef(e))return null;var n=t.options.time,i=oi(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function li(t,e,n,i){var a,r,o,s=ei.length;for(a=ei.indexOf(t);a<s-1;++a)if(o=(r=ti[ei[a]]).steps?r.steps:Qn,r.common&&Math.ceil((n-e)/(o*r.size))<=i)return ei[a];return ei[s-1]}function ui(t,e,n){var i,a,r=[],o={},s=e.length;for(i=0;i<s;++i)o[a=e[i]]=i,r.push({value:a,major:!1});return 0!==s&&n?function(t,e,n,i){var a,r,o=t._adapter,s=+o.startOf(e[0].value,i),l=e[e.length-1].value;for(a=s;a<=l;a=+o.add(a,1,i))(r=n[a])>=0&&(e[r].major=!0);return e}(t,r,o,n):r}var di=xn.extend({initialize:function(){this.mergeTicksOptions(),xn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new an._date(e.adapters.date);return Kn("time scale",n.format,"time.format","time.parser"),Kn("time scale",n.min,"time.min","ticks.min"),Kn("time scale",n.max,"time.max","ticks.max"),V.mergeIf(n.displayFormats,i.formats()),xn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),xn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=Qn,f=Jn,g=[],p=[],m=[],v=s._getLabels();for(t=0,n=v.length;t<n;++t)m.push(si(s,v[t]));for(t=0,n=(l.data.datasets||[]).length;t<n;++t)if(l.isDatasetVisible(t))if(a=l.data.datasets[t].data,V.isObject(a[0]))for(p[t]=[],e=0,i=a.length;e<i;++e)r=si(s,a[e]),g.push(r),p[t][e]=r;else p[t]=m.slice(0),o||(g=g.concat(m),o=!0);else p[t]=[];m.length&&(c=Math.min(c,m[0]),f=Math.max(f,m[m.length-1])),g.length&&(g=n>1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e<n;++e)a[i=t[e]]||(a[i]=!0,r.push(i));return r}(g).sort(ni):g.sort(ni),c=Math.min(c,g[0]),f=Math.max(f,g[g.length-1])),c=si(s,ii(d))||c,f=si(s,ai(d))||f,c=c===Qn?+u.startOf(Date.now(),h):c,f=f===Jn?+u.endOf(Date.now(),h)+1:f,s.min=Math.min(c,f),s.max=Math.max(c+1,f),s._table=[],s._timestamps={data:g,datasets:p,labels:m}},buildTicks:function(){var t,e,n,i=this,a=i.min,r=i.max,o=i.options,s=o.ticks,l=o.time,u=i._timestamps,d=[],h=i.getLabelCapacity(a),c=s.source,f=o.distribution;for(u="data"===c||"auto"===c&&"series"===f?u.data:"labels"===c?u.labels:function(t,e,n,i){var a,r=t._adapter,o=t.options,s=o.time,l=s.unit||li(s.minUnit,e,n,i),u=Zn([s.stepSize,s.unitStepSize,1]),d="week"===l&&s.isoWeekday,h=e,c=[];if(d&&(h=+r.startOf(h,"isoWeek",d)),h=+r.startOf(h,d?"day":l),r.diff(n,e,l)>1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a<n;a=+r.add(a,u,l))c.push(a);return a!==n&&"ticks"!==o.bounds||c.push(a),c}(i,a,r,h),"ticks"===o.bounds&&u.length&&(a=u[0],r=u[u.length-1]),a=si(i,ii(o))||a,r=si(i,ai(o))||r,t=0,e=u.length;t<e;++t)(n=u[t])>=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?li(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ei.length-1;r>=ei.indexOf(n);r--)if(o=ei[r],ti[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ei[n?ei.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ei.indexOf(t)+1,n=ei.length;e<n;++e)if(ti[ei[e]].common)return ei[e]}(i._unit):void 0,i._table=function(t,e,n,i){if("linear"===i||!t.length)return[{time:e,pos:0},{time:n,pos:1}];var a,r,o,s,l,u=[],d=[e];for(a=0,r=t.length;a<r;++a)(s=t[a])>e&&s<n&&d.push(s);for(d.push(n),a=0,r=d.length;a<r;++a)l=d[a+1],o=d[a-1],s=d[a],void 0!==o&&void 0!==l&&Math.round((l+o)/2)===s||u.push({time:s,pos:a/(r-1)});return u}(i._timestamps.data,a,r,f),i._offsets=function(t,e,n,i,a){var r,o,s=0,l=0;return a.offset&&e.length&&(r=ri(t,"time",e[0],"pos"),s=1===e.length?1-r:(ri(t,"time",e[1],"pos")-r)/2,o=ri(t,"time",e[e.length-1],"pos"),l=1===e.length?o:(o-ri(t,"time",e[e.length-2],"pos"))/2),{start:s,end:l,factor:1/(s+1+l)}}(i._table,d,0,0,o),s.reverse&&d.reverse(),ui(i,d,i._majorUnit)},getLabelForIndex:function(t,e){var n=this,i=n._adapter,a=n.chart.data,r=n.options.time,o=a.labels&&t<a.labels.length?a.labels[t]:"",s=a.datasets[e].data[t];return V.isObject(s)&&(o=n.getRightValue(s)),r.tooltipFormat?i.format(oi(n,o),r.tooltipFormat):"string"==typeof o?o:i.format(oi(n,o),r.displayFormats.datetime)},tickFormatFunction:function(t,e,n,i){var a=this._adapter,r=this.options,o=r.time.displayFormats,s=o[this._unit],l=this._majorUnit,u=o[l],d=n[e],h=r.ticks,c=l&&u&&d&&d.major,f=a.format(t,i||(c?u:s)),g=c?h.major:h.minor,p=Zn([g.callback,g.userCallback,h.callback,h.userCallback]);return p?p(f,e,n):f},convertTicksToLabels:function(t){var e,n,i=[];for(e=0,n=t.length;e<n;++e)i.push(this.tickFormatFunction(t[e].value,e,t));return i},getPixelForOffset:function(t){var e=this._offsets,n=ri(this._table,"time",t,"pos");return this.getPixelForDecimal((e.start+n)*e.factor)},getPixelForValue:function(t,e,n){var i=null;if(void 0!==e&&void 0!==n&&(i=this._timestamps.datasets[n][e]),null===i&&(i=si(this,t)),null!==i)return this.getPixelForOffset(i)},getPixelForTick:function(t){var e=this.getTicks();return t>=0&&t<e.length?this.getPixelForOffset(e[t].value):null},getValueForPixel:function(t){var e=this._offsets,n=this.getDecimalForPixel(t)/e.factor-e.end,i=ri(this._table,"pos",n,"time");return this._adapter._create(i)},_getLabelSize:function(t){var e=this.options.ticks,n=this.ctx.measureText(t).width,i=V.toRadians(this.isHorizontal()?e.maxRotation:e.minRotation),a=Math.cos(i),r=Math.sin(i),o=$n(e.fontSize,z.global.defaultFontSize);return{w:n*a+o*r,h:n*r+o*a}},getLabelWidth:function(t){return this._getLabelSize(t).w},getLabelCapacity:function(t){var e=this,n=e.options.time,i=n.displayFormats,a=i[n.unit]||i.millisecond,r=e.tickFormatFunction(t,0,ui(e,[t],e._majorUnit),a),o=e._getLabelSize(r),s=Math.floor(e.isHorizontal()?e.width/o.w:e.height/o.h);return e.options.offset&&s--,s>0?s:1}}),hi={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};di._defaults=hi;var ci={category:_n,linear:Dn,logarithmic:Rn,radialLinear:Gn,time:di},fi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};an._date.override("function"==typeof t?{_id:"moment",formats:function(){return fi},parse:function(e,n){return"string"==typeof e&&"string"==typeof n?e=t(e,n):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,n){return t(e).format(n)},add:function(e,n,i){return t(e).add(n,i).valueOf()},diff:function(e,n,i){return t(e).diff(t(n),i)},startOf:function(e,n,i){return e=t(e),"isoWeek"===n?e.isoWeekday(i).valueOf():e.startOf(n).valueOf()},endOf:function(e,n){return t(e).endOf(n).valueOf()},_create:function(e){return t(e)}}:{}),z._set("global",{plugins:{filler:{propagate:!0}}});var gi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e<r&&a[e]._view||null}:null},boundary:function(t){var e=t.boundary,n=e?e.x:null,i=e?e.y:null;return V.isArray(e)?function(t,n){return e[n]}:function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};function pi(t,e,n){var i,a=t._model||{},r=a.fill;if(void 0===r&&(r=!!a.backgroundColor),!1===r||null===r)return!1;if(!0===r)return"origin";if(i=parseFloat(r,10),isFinite(i)&&Math.floor(i)===i)return"-"!==r[0]&&"+"!==r[0]||(i=e+i),!(i===e||i<0||i>=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function mi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a<l;++a)r="start"===u||"end"===u?o.getPointPositionForValue(a,"start"===u?e:n):o.getBasePosition(a),s.gridLines.circular&&(r.cx=i.x,r.cy=i.y,r.angle=o.getIndexAngle(a)-Math.PI/2),d.push(r);return d}(t):function(t){var e,n=t.el._model||{},i=t.el._scale||{},a=t.fill,r=null;if(isFinite(a))return null;if("start"===a?r=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===a?r=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?r=n.scaleZero:i.getBasePixel&&(r=i.getBasePixel()),null!=r){if(void 0!==r.x&&void 0!==r.y)return r;if(V.isFinite(r))return{x:(e=i.isHorizontal())?r:null,y:e?null:r}}return null}(t)}function vi(t,e,n){var i,a=t[e].fill,r=[e];if(!n)return a;for(;!1!==a&&-1===r.indexOf(a);){if(!isFinite(a))return a;if(!(i=t[a]))return!1;if(i.visible)return a;r.push(a),a=i.fill}return!1}function bi(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),gi[n](t))}function xi(t){return t&&!t.skip}function yi(t,e,n,i,a){var r,o,s,l;if(i&&a){for(t.moveTo(e[0].x,e[0].y),r=1;r<i;++r)V.canvas.lineTo(t,e[r-1],e[r]);if(void 0===n[0].angle)for(t.lineTo(n[a-1].x,n[a-1].y),r=a-1;r>0;--r)V.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function _i(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,p=i.spanGaps,m=[],v=[],b=0,x=0;for(t.beginPath(),o=0,s=g;o<s;++o)d=n(u=e[l=o%g]._view,l,i),h=xi(u),c=xi(d),r&&void 0===f&&h&&(s=g+(f=o+1)),h&&c?(b=m.push(u),x=v.push(d)):b&&x&&(p?(h&&m.push(u),c&&v.push(d)):(yi(t,m,v,b,x),b=x=0,m=[],v=[]));yi(t,m,v,b,x),t.closePath(),t.fillStyle=a,t.fill()}var ki={id:"filler",afterDatasetsUpdate:function(t,e){var n,i,a,r,o=(t.data.datasets||[]).length,s=e.propagate,l=[];for(i=0;i<o;++i)r=null,(a=(n=t.getDatasetMeta(i)).dataset)&&a._model&&a instanceof _t.Line&&(r={visible:t.isDatasetVisible(i),fill:pi(a,i,o),chart:t,el:a}),n.$filler=r,l.push(r);for(i=0;i<o;++i)(r=l[i])&&(r.fill=vi(l,i,s),r.boundary=mi(r),r.mapper=bi(r))},beforeDatasetsDraw:function(t){var e,n,i,a,r,o,s,l=t._getSortedVisibleDatasetMetas(),u=t.ctx;for(n=l.length-1;n>=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||z.global.defaultColor,o&&s&&r.length&&(V.canvas.clipArea(u,t.chartArea),_i(u,r,o,a,s,i._loop),V.canvas.unclipArea(u)))}},wi=V.rtl.getRtlAdapter,Mi=V.noop,Si=V.valueOrDefault;function Ci(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}z._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;e<n;e++)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=r[e].backgroundColor,r[e].label&&i.appendChild(document.createTextNode(r[e].label));return a.outerHTML}});var Pi=X.extend({initialize:function(t){V.extend(this,t),this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1},beforeUpdate:Mi,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Mi,beforeSetDimensions:Mi,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Mi,beforeBuildLabels:Mi,buildLabels:function(){var t=this,e=t.options.labels||{},n=V.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(n=n.filter((function(n){return e.filter(n,t.chart.data)}))),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:Mi,beforeFit:Mi,fit:function(){var t=this,e=t.options,n=e.labels,i=e.display,a=t.ctx,r=V.options._parseFont(n),o=r.size,s=t.legendHitBoxes=[],l=t.minSize,u=t.isHorizontal();if(u?(l.width=t.maxWidth,l.height=i?10:0):(l.width=i?10:0,l.height=t.maxHeight),i){if(a.font=r.string,u){var d=t.lineWidths=[0],h=0;a.textAlign="left",a.textBaseline="middle",V.each(t.legendItems,(function(t,e){var i=Ci(n,o)+o/2+a.measureText(t.text).width;(0===e||d[d.length-1]+i+2*n.padding>l.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],p=n.padding,m=0,v=0;V.each(t.legendItems,(function(t,e){var i=Ci(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(p+=m+n.padding,f.push(m),g.push(v),m=0,v=0),m=Math.max(m,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),p+=m,f.push(m),g.push(v),l.width+=p}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Mi,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=z.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=wi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Si(n.fontColor,i.defaultFontColor),g=V.options._parseFont(n),p=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var m=Ci(n,p),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},x=t.isHorizontal();d=x?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},V.rtl.overrideTextDirection(t.ctx,e.textDirection);var y=p+n.padding;V.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=m+p/2+f,_=d.x,k=d.y;h.setWidth(t.minSize.width),x?i>0&&_+g+n.padding>t.left+t.minSize.width&&(k=d.y+=y,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&k+y>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,k=d.y=t.top+b(o,s[d.line]));var w=h.x(_);!function(t,e,i){if(!(isNaN(m)||m<=0)){c.save();var o=Si(i.lineWidth,r.borderWidth);if(c.fillStyle=Si(i.fillStyle,a),c.lineCap=Si(i.lineCap,r.borderCapStyle),c.lineDashOffset=Si(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Si(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Si(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Si(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=m*Math.SQRT2/2,l=h.xPlus(t,m/2),u=e+p/2;V.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,m),e,m,p),0!==o&&c.strokeRect(h.leftForLtr(t,m),e,m,p);c.restore()}}(w,k,e),v[i].left=h.leftForLtr(w,v[i].width),v[i].top=k,function(t,e,n,i){var a=p/2,r=h.xPlus(t,m+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(w,k,e,f),x?d.x+=g+n.padding:d.y+=y})),V.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n<a.length;++n)if(t>=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Ai(t,e){var n=new Pi({ctx:t.ctx,options:e,chart:t});ge.configure(t,n,e),ge.addBox(t,n),t.legend=n}var Di={id:"legend",_element:Pi,beforeInit:function(t){var e=t.options.legend;e&&Ai(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(V.mergeIf(e,z.global.legend),n?(ge.configure(t,n,e),n.options=e):Ai(t,e)):n&&(ge.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ti=V.noop;z._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Ii=X.extend({initialize:function(t){V.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ti,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ti,beforeSetDimensions:Ti,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ti,beforeBuildLabels:Ti,buildLabels:Ti,afterBuildLabels:Ti,beforeFit:Ti,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(V.isArray(n.text)?n.text.length:1)*V.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ti,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=V.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=V.valueOrDefault(n.fontColor,z.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(V.isArray(g))for(var p=0,m=0;m<g.length;++m)e.fillText(g[m],0,p,i),p+=s;else e.fillText(g,0,0,i);e.restore()}}});function Fi(t,e){var n=new Ii({ctx:t.ctx,options:e,chart:t});ge.configure(t,n,e),ge.addBox(t,n),t.titleBlock=n}var Li={},Oi=ki,Ri=Di,zi={id:"title",_element:Ii,beforeInit:function(t){var e=t.options.title;e&&Fi(t,e)},beforeUpdate:function(t){var e=t.options.title,n=t.titleBlock;e?(V.mergeIf(e,z.global.title),n?(ge.configure(t,n,e),n.options=e):Fi(t,e)):n&&(ge.removeBox(t,n),delete t.titleBlock)}};for(var Ni in Li.filler=Oi,Li.legend=Ri,Li.title=zi,tn.helpers=V,function(){function t(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),-1!==t.indexOf("%")&&(i=i/100*e.parentNode[n])):i=t,i}function e(t){return null!=t&&"none"!==t}function n(n,i,a){var r=document.defaultView,o=V._getParentNode(n),s=r.getComputedStyle(n)[i],l=r.getComputedStyle(o)[i],u=e(s),d=e(l),h=Number.POSITIVE_INFINITY;return u||d?Math.min(u?t(s,n,a):h,d?t(l,o,a):h):"none"}V.where=function(t,e){if(V.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return V.each(t,(function(t){e(t)&&n.push(t)})),n},V.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;i<a;++i)if(e.call(n,t[i],i,t))return i;return-1},V.findNextWhere=function(t,e,n){V.isNullOrUndef(n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},V.findPreviousWhere=function(t,e,n){V.isNullOrUndef(n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},V.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},V.almostEquals=function(t,e,n){return Math.abs(t-e)<n},V.almostWhole=function(t,e){var n=Math.round(t);return n-e<=t&&n+e>=t},V.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},V.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},V.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},V.toRadians=function(t){return t*(Math.PI/180)},V.toDegrees=function(t){return t*(180/Math.PI)},V._decimalPlaces=function(t){if(V.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},V.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},V.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},V.aliasPixel=function(t){return t%2==0?0:.5},V._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},V.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},V.EPSILON=Number.EPSILON||1e-14,V.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e<h;++e)if(!(i=d[e]).model.skip){if(n=e>0?d[e-1]:null,(a=e<h-1?d[e+1]:null)&&!a.model.skip){var c=a.model.x-i.model.x;i.deltaK=0!==c?(a.model.y-i.model.y)/c:0}!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2}for(e=0;e<h-1;++e)i=d[e],a=d[e+1],i.model.skip||a.model.skip||(V.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(r=i.mK/i.deltaK,o=a.mK/i.deltaK,(l=Math.pow(r,2)+Math.pow(o,2))<=9||(s=3/Math.sqrt(l),i.mK=r*s*i.deltaK,a.mK=o*s*i.deltaK)));for(e=0;e<h;++e)(i=d[e]).model.skip||(n=e>0?d[e-1]:null,a=e<h-1?d[e+1]:null,n&&!n.model.skip&&(u=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-u,i.model.controlPointPreviousY=i.model.y-u*i.mK),a&&!a.model.skip&&(u=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+u,i.model.controlPointNextY=i.model.y+u*i.mK))},V.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},V.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},V.niceNum=function(t,e){var n=Math.floor(V.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},V.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},V.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(V.getStyle(r,"padding-left")),u=parseFloat(V.getStyle(r,"padding-top")),d=parseFloat(V.getStyle(r,"padding-right")),h=parseFloat(V.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},V.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},V.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},V._calculatePadding=function(t,e,n){return(e=V.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},V._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},V.getMaximumWidth=function(t){var e=V._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-V._calculatePadding(e,"padding-left",n)-V._calculatePadding(e,"padding-right",n),a=V.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},V.getMaximumHeight=function(t){var e=V._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-V._calculatePadding(e,"padding-top",n)-V._calculatePadding(e,"padding-bottom",n),a=V.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},V.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},V.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},V.fontString=function(t,e,n){return e+" "+t+"px "+n},V.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;o<c;o++)if(null!=(u=n[o])&&!0!==V.isArray(u))h=V.measureText(t,a,r,h,u);else if(V.isArray(u))for(s=0,l=u.length;s<l;s++)null==(d=u[s])||V.isArray(d)||(h=V.measureText(t,a,r,h,d));var f=r.length/2;if(f>n.length){for(o=0;o<f;o++)delete a[r[o]];r.splice(0,f)}return h},V.measureText=function(t,e,n,i,a){var r=e[a];return r||(r=e[a]=t.measureText(a).width,n.push(a)),r>i&&(i=r),i},V.numberOfLabelLines=function(t){var e=1;return V.each(t,(function(t){V.isArray(t)&&t.length>e&&(e=t.length)})),e},V.color=k?function(t){return t instanceof CanvasGradient&&(t=z.global.defaultColor),k(t)}:function(t){return console.error("Color.js not found!"),t},V.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:V.color(t).saturate(.5).darken(.1).rgbString()}}(),tn._adapters=an,tn.Animation=Z,tn.animationService=$,tn.controllers=$t,tn.DatasetController=nt,tn.defaults=z,tn.Element=X,tn.elements=_t,tn.Interaction=ae,tn.layouts=ge,tn.platform=Fe,tn.plugins=Le,tn.Scale=xn,tn.scaleService=Oe,tn.Ticks=rn,tn.Tooltip=Ue,tn.helpers.each(ci,(function(t,e){tn.scaleService.registerScaleType(e,t,t._defaults)})),Li)Li.hasOwnProperty(Ni)&&tn.plugins.register(Li[Ni]);tn.platform.initialize();var Bi=tn;return"undefined"!=typeof window&&(window.Chart=tn),tn.Chart=tn,tn.Legend=Li.legend._element,tn.Title=Li.title._element,tn.pluginService=tn.plugins,tn.PluginBase=tn.Element.extend({}),tn.canvasHelpers=tn.helpers.canvas,tn.layoutService=tn.layouts,tn.LinearScaleBase=Sn,tn.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){tn[t]=function(e,n){return new tn(e,tn.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Bi}));
|
|
lib/Chart_js/bower.json
DELETED
@@ -1,11 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"name": "Chart.js",
|
3 |
-
"version": "1.0.1-beta.4",
|
4 |
-
"description": "Simple HTML5 Charts using the canvas element",
|
5 |
-
"homepage": "https://github.com/nnnick/Chart.js",
|
6 |
-
"author": "nnnick",
|
7 |
-
"main": [
|
8 |
-
"Chart.min.js"
|
9 |
-
],
|
10 |
-
"dependencies": {}
|
11 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/docs/00-Getting-Started.md
DELETED
@@ -1,200 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Getting started
|
3 |
-
anchor: getting-started
|
4 |
-
---
|
5 |
-
|
6 |
-
###Include Chart.js
|
7 |
-
|
8 |
-
First we need to include the Chart.js library on the page. The library occupies a global variable of `Chart`.
|
9 |
-
|
10 |
-
```html
|
11 |
-
<script src="Chart.js"></script>
|
12 |
-
```
|
13 |
-
|
14 |
-
Alternatively, if you're using an AMD loader for JavaScript modules, that is also supported in the Chart.js core. Please note: the library will still occupy a global variable of `Chart`, even if it detects `define` and `define.amd`. If this is a problem, you can call `noConflict` to restore the global Chart variable to it's previous owner.
|
15 |
-
|
16 |
-
```javascript
|
17 |
-
// Using requirejs
|
18 |
-
require(['path/to/Chartjs'], function(Chart){
|
19 |
-
// Use Chart.js as normal here.
|
20 |
-
|
21 |
-
// Chart.noConflict restores the Chart global variable to it's previous owner
|
22 |
-
// The function returns what was previously Chart, allowing you to reassign.
|
23 |
-
var Chartjs = Chart.noConflict();
|
24 |
-
|
25 |
-
});
|
26 |
-
```
|
27 |
-
|
28 |
-
You can also grab Chart.js using bower:
|
29 |
-
|
30 |
-
```bash
|
31 |
-
bower install chartjs --save
|
32 |
-
```
|
33 |
-
|
34 |
-
###Creating a chart
|
35 |
-
|
36 |
-
To create a chart, we need to instantiate the `Chart` class. To do this, we need to pass in the 2d context of where we want to draw the chart. Here's an example.
|
37 |
-
|
38 |
-
```html
|
39 |
-
<canvas id="myChart" width="400" height="400"></canvas>
|
40 |
-
```
|
41 |
-
|
42 |
-
```javascript
|
43 |
-
// Get the context of the canvas element we want to select
|
44 |
-
var ctx = document.getElementById("myChart").getContext("2d");
|
45 |
-
var myNewChart = new Chart(ctx).PolarArea(data);
|
46 |
-
```
|
47 |
-
|
48 |
-
We can also get the context of our canvas with jQuery. To do this, we need to get the DOM node out of the jQuery collection, and call the `getContext("2d")` method on that.
|
49 |
-
|
50 |
-
```javascript
|
51 |
-
// Get context with jQuery - using jQuery's .get() method.
|
52 |
-
var ctx = $("#myChart").get(0).getContext("2d");
|
53 |
-
// This will get the first returned node in the jQuery collection.
|
54 |
-
var myNewChart = new Chart(ctx);
|
55 |
-
```
|
56 |
-
|
57 |
-
After we've instantiated the Chart class on the canvas we want to draw on, Chart.js will handle the scaling for retina displays.
|
58 |
-
|
59 |
-
With the Chart class set up, we can go on to create one of the charts Chart.js has available. In the example below, we would be drawing a Polar area chart.
|
60 |
-
|
61 |
-
```javascript
|
62 |
-
new Chart(ctx).PolarArea(data, options);
|
63 |
-
```
|
64 |
-
|
65 |
-
We call a method of the name of the chart we want to create. We pass in the data for that chart type, and the options for that chart as parameters. Chart.js will merge the global defaults with chart type specific defaults, then merge any options passed in as a second argument after data.
|
66 |
-
|
67 |
-
###Global chart configuration
|
68 |
-
|
69 |
-
This concept was introduced in Chart.js 1.0 to keep configuration DRY, and allow for changing options globally across chart types, avoiding the need to specify options for each instance, or the default for a particular chart type.
|
70 |
-
|
71 |
-
```javascript
|
72 |
-
Chart.defaults.global = {
|
73 |
-
// Boolean - Whether to animate the chart
|
74 |
-
animation: true,
|
75 |
-
|
76 |
-
// Number - Number of animation steps
|
77 |
-
animationSteps: 60,
|
78 |
-
|
79 |
-
// String - Animation easing effect
|
80 |
-
animationEasing: "easeOutQuart",
|
81 |
-
|
82 |
-
// Boolean - If we should show the scale at all
|
83 |
-
showScale: true,
|
84 |
-
|
85 |
-
// Boolean - If we want to override with a hard coded scale
|
86 |
-
scaleOverride: false,
|
87 |
-
|
88 |
-
// ** Required if scaleOverride is true **
|
89 |
-
// Number - The number of steps in a hard coded scale
|
90 |
-
scaleSteps: null,
|
91 |
-
// Number - The value jump in the hard coded scale
|
92 |
-
scaleStepWidth: null,
|
93 |
-
// Number - The scale starting value
|
94 |
-
scaleStartValue: null,
|
95 |
-
|
96 |
-
// String - Colour of the scale line
|
97 |
-
scaleLineColor: "rgba(0,0,0,.1)",
|
98 |
-
|
99 |
-
// Number - Pixel width of the scale line
|
100 |
-
scaleLineWidth: 1,
|
101 |
-
|
102 |
-
// Boolean - Whether to show labels on the scale
|
103 |
-
scaleShowLabels: true,
|
104 |
-
|
105 |
-
// Interpolated JS string - can access value
|
106 |
-
scaleLabel: "<%=value%>",
|
107 |
-
|
108 |
-
// Boolean - Whether the scale should stick to integers, not floats even if drawing space is there
|
109 |
-
scaleIntegersOnly: true,
|
110 |
-
|
111 |
-
// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
|
112 |
-
scaleBeginAtZero: false,
|
113 |
-
|
114 |
-
// String - Scale label font declaration for the scale label
|
115 |
-
scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
116 |
-
|
117 |
-
// Number - Scale label font size in pixels
|
118 |
-
scaleFontSize: 12,
|
119 |
-
|
120 |
-
// String - Scale label font weight style
|
121 |
-
scaleFontStyle: "normal",
|
122 |
-
|
123 |
-
// String - Scale label font colour
|
124 |
-
scaleFontColor: "#666",
|
125 |
-
|
126 |
-
// Boolean - whether or not the chart should be responsive and resize when the browser does.
|
127 |
-
responsive: false,
|
128 |
-
|
129 |
-
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
|
130 |
-
maintainAspectRatio: true,
|
131 |
-
|
132 |
-
// Boolean - Determines whether to draw tooltips on the canvas or not
|
133 |
-
showTooltips: true,
|
134 |
-
|
135 |
-
// Array - Array of string names to attach tooltip events
|
136 |
-
tooltipEvents: ["mousemove", "touchstart", "touchmove"],
|
137 |
-
|
138 |
-
// String - Tooltip background colour
|
139 |
-
tooltipFillColor: "rgba(0,0,0,0.8)",
|
140 |
-
|
141 |
-
// String - Tooltip label font declaration for the scale label
|
142 |
-
tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
143 |
-
|
144 |
-
// Number - Tooltip label font size in pixels
|
145 |
-
tooltipFontSize: 14,
|
146 |
-
|
147 |
-
// String - Tooltip font weight style
|
148 |
-
tooltipFontStyle: "normal",
|
149 |
-
|
150 |
-
// String - Tooltip label font colour
|
151 |
-
tooltipFontColor: "#fff",
|
152 |
-
|
153 |
-
// String - Tooltip title font declaration for the scale label
|
154 |
-
tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
155 |
-
|
156 |
-
// Number - Tooltip title font size in pixels
|
157 |
-
tooltipTitleFontSize: 14,
|
158 |
-
|
159 |
-
// String - Tooltip title font weight style
|
160 |
-
tooltipTitleFontStyle: "bold",
|
161 |
-
|
162 |
-
// String - Tooltip title font colour
|
163 |
-
tooltipTitleFontColor: "#fff",
|
164 |
-
|
165 |
-
// Number - pixel width of padding around tooltip text
|
166 |
-
tooltipYPadding: 6,
|
167 |
-
|
168 |
-
// Number - pixel width of padding around tooltip text
|
169 |
-
tooltipXPadding: 6,
|
170 |
-
|
171 |
-
// Number - Size of the caret on the tooltip
|
172 |
-
tooltipCaretSize: 8,
|
173 |
-
|
174 |
-
// Number - Pixel radius of the tooltip border
|
175 |
-
tooltipCornerRadius: 6,
|
176 |
-
|
177 |
-
// Number - Pixel offset from point x to tooltip edge
|
178 |
-
tooltipXOffset: 10,
|
179 |
-
{% raw %}
|
180 |
-
// String - Template string for single tooltips
|
181 |
-
tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>",
|
182 |
-
{% endraw %}
|
183 |
-
// String - Template string for single tooltips
|
184 |
-
multiTooltipTemplate: "<%= value %>",
|
185 |
-
|
186 |
-
// Function - Will fire on animation progression.
|
187 |
-
onAnimationProgress: function(){},
|
188 |
-
|
189 |
-
// Function - Will fire on animation completion.
|
190 |
-
onAnimationComplete: function(){}
|
191 |
-
}
|
192 |
-
```
|
193 |
-
|
194 |
-
If for example, you wanted all charts created to be responsive, and resize when the browser window does, the following setting can be changed:
|
195 |
-
|
196 |
-
```javascript
|
197 |
-
Chart.defaults.global.responsive = true;
|
198 |
-
```
|
199 |
-
|
200 |
-
Now, every time we create a chart, `options.responsive` will be `true`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/docs/01-Line-Chart.md
DELETED
@@ -1,160 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Line Chart
|
3 |
-
anchor: line-chart
|
4 |
-
---
|
5 |
-
###Introduction
|
6 |
-
A line chart is a way of plotting data points on a line.
|
7 |
-
|
8 |
-
Often, it is used to show trend data, and the comparison of two data sets.
|
9 |
-
|
10 |
-
<div class="canvas-holder">
|
11 |
-
<canvas width="250" height="125"></canvas>
|
12 |
-
</div>
|
13 |
-
|
14 |
-
###Example usage
|
15 |
-
```javascript
|
16 |
-
var myLineChart = new Chart(ctx).Line(data, options);
|
17 |
-
```
|
18 |
-
###Data structure
|
19 |
-
|
20 |
-
```javascript
|
21 |
-
var data = {
|
22 |
-
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
23 |
-
datasets: [
|
24 |
-
{
|
25 |
-
label: "My First dataset",
|
26 |
-
fillColor: "rgba(220,220,220,0.2)",
|
27 |
-
strokeColor: "rgba(220,220,220,1)",
|
28 |
-
pointColor: "rgba(220,220,220,1)",
|
29 |
-
pointStrokeColor: "#fff",
|
30 |
-
pointHighlightFill: "#fff",
|
31 |
-
pointHighlightStroke: "rgba(220,220,220,1)",
|
32 |
-
data: [65, 59, 80, 81, 56, 55, 40]
|
33 |
-
},
|
34 |
-
{
|
35 |
-
label: "My Second dataset",
|
36 |
-
fillColor: "rgba(151,187,205,0.2)",
|
37 |
-
strokeColor: "rgba(151,187,205,1)",
|
38 |
-
pointColor: "rgba(151,187,205,1)",
|
39 |
-
pointStrokeColor: "#fff",
|
40 |
-
pointHighlightFill: "#fff",
|
41 |
-
pointHighlightStroke: "rgba(151,187,205,1)",
|
42 |
-
data: [28, 48, 40, 19, 86, 27, 90]
|
43 |
-
}
|
44 |
-
]
|
45 |
-
};
|
46 |
-
```
|
47 |
-
|
48 |
-
The line chart requires an array of labels for each of the data points. This is shown on the X axis.
|
49 |
-
The data for line charts is broken up into an array of datasets. Each dataset has a colour for the fill, a colour for the line and colours for the points and strokes of the points. These colours are strings just like CSS. You can use RGBA, RGB, HEX or HSL notation.
|
50 |
-
|
51 |
-
The label key on each dataset is optional, and can be used when generating a scale for the chart.
|
52 |
-
|
53 |
-
### Chart options
|
54 |
-
|
55 |
-
These are the customisation options specific to Line charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
|
56 |
-
|
57 |
-
```javascript
|
58 |
-
{
|
59 |
-
|
60 |
-
///Boolean - Whether grid lines are shown across the chart
|
61 |
-
scaleShowGridLines : true,
|
62 |
-
|
63 |
-
//String - Colour of the grid lines
|
64 |
-
scaleGridLineColor : "rgba(0,0,0,.05)",
|
65 |
-
|
66 |
-
//Number - Width of the grid lines
|
67 |
-
scaleGridLineWidth : 1,
|
68 |
-
|
69 |
-
//Boolean - Whether the line is curved between points
|
70 |
-
bezierCurve : true,
|
71 |
-
|
72 |
-
//Number - Tension of the bezier curve between points
|
73 |
-
bezierCurveTension : 0.4,
|
74 |
-
|
75 |
-
//Boolean - Whether to show a dot for each point
|
76 |
-
pointDot : true,
|
77 |
-
|
78 |
-
//Number - Radius of each point dot in pixels
|
79 |
-
pointDotRadius : 4,
|
80 |
-
|
81 |
-
//Number - Pixel width of point dot stroke
|
82 |
-
pointDotStrokeWidth : 1,
|
83 |
-
|
84 |
-
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
85 |
-
pointHitDetectionRadius : 20,
|
86 |
-
|
87 |
-
//Boolean - Whether to show a stroke for datasets
|
88 |
-
datasetStroke : true,
|
89 |
-
|
90 |
-
//Number - Pixel width of dataset stroke
|
91 |
-
datasetStrokeWidth : 2,
|
92 |
-
|
93 |
-
//Boolean - Whether to fill the dataset with a colour
|
94 |
-
datasetFill : true,
|
95 |
-
{% raw %}
|
96 |
-
//String - A legend template
|
97 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].lineColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
98 |
-
{% endraw %}
|
99 |
-
};
|
100 |
-
```
|
101 |
-
|
102 |
-
You can override these for your `Chart` instance by passing a second argument into the `Line` method as an object with the keys you want to override.
|
103 |
-
|
104 |
-
For example, we could have a line chart without bezier curves between points by doing the following:
|
105 |
-
|
106 |
-
```javascript
|
107 |
-
new Chart(ctx).Line(data, {
|
108 |
-
bezierCurve: false
|
109 |
-
});
|
110 |
-
// This will create a chart with all of the default options, merged from the global config,
|
111 |
-
// and the Line chart defaults, but this particular instance will have `bezierCurve` set to false.
|
112 |
-
```
|
113 |
-
|
114 |
-
We can also change these defaults values for each Line type that is created, this object is available at `Chart.defaults.Line`.
|
115 |
-
|
116 |
-
|
117 |
-
### Prototype methods
|
118 |
-
|
119 |
-
#### .getPointsAtEvent( event )
|
120 |
-
|
121 |
-
Calling `getPointsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the point elements that are at that the same position of that event.
|
122 |
-
|
123 |
-
```javascript
|
124 |
-
canvas.onclick = function(evt){
|
125 |
-
var activePoints = myLineChart.getPointsAtEvent(evt);
|
126 |
-
// => activePoints is an array of points on the canvas that are at the same position as the click event.
|
127 |
-
};
|
128 |
-
```
|
129 |
-
|
130 |
-
This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
|
131 |
-
|
132 |
-
#### .update( )
|
133 |
-
|
134 |
-
Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop.
|
135 |
-
|
136 |
-
```javascript
|
137 |
-
myLineChart.datasets[0].points[2].value = 50;
|
138 |
-
// Would update the first dataset's value of 'March' to be 50
|
139 |
-
myLineChart.update();
|
140 |
-
// Calling update now animates the position of March from 90 to 50.
|
141 |
-
```
|
142 |
-
|
143 |
-
#### .addData( valuesArray, label )
|
144 |
-
|
145 |
-
Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those points.
|
146 |
-
|
147 |
-
```javascript
|
148 |
-
// The values array passed into addData should be one for each dataset in the chart
|
149 |
-
myLineChart.addData([40, 60], "August");
|
150 |
-
// This new data will now animate at the end of the chart.
|
151 |
-
```
|
152 |
-
|
153 |
-
#### .removeData( )
|
154 |
-
|
155 |
-
Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart.
|
156 |
-
|
157 |
-
```javascript
|
158 |
-
myLineChart.removeData();
|
159 |
-
// The chart will remove the first point and animate other points into place
|
160 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/docs/02-Bar-Chart.md
DELETED
@@ -1,143 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Bar Chart
|
3 |
-
anchor: bar-chart
|
4 |
-
---
|
5 |
-
|
6 |
-
### Introduction
|
7 |
-
A bar chart is a way of showing data as bars.
|
8 |
-
|
9 |
-
It is sometimes used to show trend data, and the comparison of multiple data sets side by side.
|
10 |
-
|
11 |
-
<div class="canvas-holder">
|
12 |
-
<canvas width="250" height="125"></canvas>
|
13 |
-
</div>
|
14 |
-
|
15 |
-
### Example usage
|
16 |
-
```javascript
|
17 |
-
var myBarChart = new Chart(ctx).Bar(data, options);
|
18 |
-
```
|
19 |
-
|
20 |
-
### Data structure
|
21 |
-
|
22 |
-
```javascript
|
23 |
-
var data = {
|
24 |
-
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
25 |
-
datasets: [
|
26 |
-
{
|
27 |
-
label: "My First dataset",
|
28 |
-
fillColor: "rgba(220,220,220,0.5)",
|
29 |
-
strokeColor: "rgba(220,220,220,0.8)",
|
30 |
-
highlightFill: "rgba(220,220,220,0.75)",
|
31 |
-
highlightStroke: "rgba(220,220,220,1)",
|
32 |
-
data: [65, 59, 80, 81, 56, 55, 40]
|
33 |
-
},
|
34 |
-
{
|
35 |
-
label: "My Second dataset",
|
36 |
-
fillColor: "rgba(151,187,205,0.5)",
|
37 |
-
strokeColor: "rgba(151,187,205,0.8)",
|
38 |
-
highlightFill: "rgba(151,187,205,0.75)",
|
39 |
-
highlightStroke: "rgba(151,187,205,1)",
|
40 |
-
data: [28, 48, 40, 19, 86, 27, 90]
|
41 |
-
}
|
42 |
-
]
|
43 |
-
};
|
44 |
-
```
|
45 |
-
The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data. Again, colours are in CSS format.
|
46 |
-
We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example.
|
47 |
-
|
48 |
-
The label key on each dataset is optional, and can be used when generating a scale for the chart.
|
49 |
-
|
50 |
-
### Chart Options
|
51 |
-
|
52 |
-
These are the customisation options specific to Bar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
|
53 |
-
|
54 |
-
```javascript
|
55 |
-
{
|
56 |
-
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
|
57 |
-
scaleBeginAtZero : true,
|
58 |
-
|
59 |
-
//Boolean - Whether grid lines are shown across the chart
|
60 |
-
scaleShowGridLines : true,
|
61 |
-
|
62 |
-
//String - Colour of the grid lines
|
63 |
-
scaleGridLineColor : "rgba(0,0,0,.05)",
|
64 |
-
|
65 |
-
//Number - Width of the grid lines
|
66 |
-
scaleGridLineWidth : 1,
|
67 |
-
|
68 |
-
//Boolean - If there is a stroke on each bar
|
69 |
-
barShowStroke : true,
|
70 |
-
|
71 |
-
//Number - Pixel width of the bar stroke
|
72 |
-
barStrokeWidth : 2,
|
73 |
-
|
74 |
-
//Number - Spacing between each of the X value sets
|
75 |
-
barValueSpacing : 5,
|
76 |
-
|
77 |
-
//Number - Spacing between data sets within X values
|
78 |
-
barDatasetSpacing : 1,
|
79 |
-
{% raw %}
|
80 |
-
//String - A legend template
|
81 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].lineColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
82 |
-
{% endraw %}
|
83 |
-
}
|
84 |
-
```
|
85 |
-
|
86 |
-
You can override these for your `Chart` instance by passing a second argument into the `Bar` method as an object with the keys you want to override.
|
87 |
-
|
88 |
-
For example, we could have a bar chart without a stroke on each bar by doing the following:
|
89 |
-
|
90 |
-
```javascript
|
91 |
-
new Chart(ctx).Bar(data, {
|
92 |
-
barShowStroke: false
|
93 |
-
});
|
94 |
-
// This will create a chart with all of the default options, merged from the global config,
|
95 |
-
// and the Bar chart defaults but this particular instance will have `barShowStroke` set to false.
|
96 |
-
```
|
97 |
-
|
98 |
-
We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.Bar`.
|
99 |
-
|
100 |
-
### Prototype methods
|
101 |
-
|
102 |
-
#### .getBarsAtEvent( event )
|
103 |
-
|
104 |
-
Calling `getBarsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the bar elements that are at that the same position of that event.
|
105 |
-
|
106 |
-
```javascript
|
107 |
-
canvas.onclick = function(evt){
|
108 |
-
var activeBars = myBarChart.getBarsAtEvent(evt);
|
109 |
-
// => activeBars is an array of bars on the canvas that are at the same position as the click event.
|
110 |
-
};
|
111 |
-
```
|
112 |
-
|
113 |
-
This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
|
114 |
-
|
115 |
-
#### .update( )
|
116 |
-
|
117 |
-
Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop.
|
118 |
-
|
119 |
-
```javascript
|
120 |
-
myBarChart.datasets[0].bars[2].value = 50;
|
121 |
-
// Would update the first dataset's value of 'March' to be 50
|
122 |
-
myBarChart.update();
|
123 |
-
// Calling update now animates the position of March from 90 to 50.
|
124 |
-
```
|
125 |
-
|
126 |
-
#### .addData( valuesArray, label )
|
127 |
-
|
128 |
-
Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those bars.
|
129 |
-
|
130 |
-
```javascript
|
131 |
-
// The values array passed into addData should be one for each dataset in the chart
|
132 |
-
myBarChart.addData([40, 60], "August");
|
133 |
-
// The new data will now animate at the end of the chart.
|
134 |
-
```
|
135 |
-
|
136 |
-
#### .removeData( )
|
137 |
-
|
138 |
-
Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart.
|
139 |
-
|
140 |
-
```javascript
|
141 |
-
myBarChart.removeData();
|
142 |
-
// The chart will now animate and remove the first bar
|
143 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/docs/03-Radar-Chart.md
DELETED
@@ -1,177 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Radar Chart
|
3 |
-
anchor: radar-chart
|
4 |
-
---
|
5 |
-
|
6 |
-
###Introduction
|
7 |
-
A radar chart is a way of showing multiple data points and the variation between them.
|
8 |
-
|
9 |
-
They are often useful for comparing the points of two or more different data sets.
|
10 |
-
|
11 |
-
<div class="canvas-holder">
|
12 |
-
<canvas width="250" height="125"></canvas>
|
13 |
-
</div>
|
14 |
-
|
15 |
-
###Example usage
|
16 |
-
|
17 |
-
```javascript
|
18 |
-
var myRadarChart = new Chart(ctx).Radar(data, options);
|
19 |
-
```
|
20 |
-
|
21 |
-
###Data structure
|
22 |
-
```javascript
|
23 |
-
var data = {
|
24 |
-
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
|
25 |
-
datasets: [
|
26 |
-
{
|
27 |
-
label: "My First dataset",
|
28 |
-
fillColor: "rgba(220,220,220,0.2)",
|
29 |
-
strokeColor: "rgba(220,220,220,1)",
|
30 |
-
pointColor: "rgba(220,220,220,1)",
|
31 |
-
pointStrokeColor: "#fff",
|
32 |
-
pointHighlightFill: "#fff",
|
33 |
-
pointHighlightStroke: "rgba(220,220,220,1)",
|
34 |
-
data: [65, 59, 90, 81, 56, 55, 40]
|
35 |
-
},
|
36 |
-
{
|
37 |
-
label: "My Second dataset",
|
38 |
-
fillColor: "rgba(151,187,205,0.2)",
|
39 |
-
strokeColor: "rgba(151,187,205,1)",
|
40 |
-
pointColor: "rgba(151,187,205,1)",
|
41 |
-
pointStrokeColor: "#fff",
|
42 |
-
pointHighlightFill: "#fff",
|
43 |
-
pointHighlightStroke: "rgba(151,187,205,1)",
|
44 |
-
data: [28, 48, 40, 19, 96, 27, 100]
|
45 |
-
}
|
46 |
-
]
|
47 |
-
};
|
48 |
-
```
|
49 |
-
For a radar chart, to provide context of what each point means, we include an array of strings that show around each point in the chart.
|
50 |
-
For the radar chart data, we have an array of datasets. Each of these is an object, with a fill colour, a stroke colour, a colour for the fill of each point, and a colour for the stroke of each point. We also have an array of data values.
|
51 |
-
|
52 |
-
The label key on each dataset is optional, and can be used when generating a scale for the chart.
|
53 |
-
|
54 |
-
### Chart options
|
55 |
-
|
56 |
-
These are the customisation options specific to Radar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
|
57 |
-
|
58 |
-
|
59 |
-
```javascript
|
60 |
-
{
|
61 |
-
//Boolean - Whether to show lines for each scale point
|
62 |
-
scaleShowLine : true,
|
63 |
-
|
64 |
-
//Boolean - Whether we show the angle lines out of the radar
|
65 |
-
angleShowLineOut : true,
|
66 |
-
|
67 |
-
//Boolean - Whether to show labels on the scale
|
68 |
-
scaleShowLabels : false,
|
69 |
-
|
70 |
-
// Boolean - Whether the scale should begin at zero
|
71 |
-
scaleBeginAtZero : true,
|
72 |
-
|
73 |
-
//String - Colour of the angle line
|
74 |
-
angleLineColor : "rgba(0,0,0,.1)",
|
75 |
-
|
76 |
-
//Number - Pixel width of the angle line
|
77 |
-
angleLineWidth : 1,
|
78 |
-
|
79 |
-
//String - Point label font declaration
|
80 |
-
pointLabelFontFamily : "'Arial'",
|
81 |
-
|
82 |
-
//String - Point label font weight
|
83 |
-
pointLabelFontStyle : "normal",
|
84 |
-
|
85 |
-
//Number - Point label font size in pixels
|
86 |
-
pointLabelFontSize : 10,
|
87 |
-
|
88 |
-
//String - Point label font colour
|
89 |
-
pointLabelFontColor : "#666",
|
90 |
-
|
91 |
-
//Boolean - Whether to show a dot for each point
|
92 |
-
pointDot : true,
|
93 |
-
|
94 |
-
//Number - Radius of each point dot in pixels
|
95 |
-
pointDotRadius : 3,
|
96 |
-
|
97 |
-
//Number - Pixel width of point dot stroke
|
98 |
-
pointDotStrokeWidth : 1,
|
99 |
-
|
100 |
-
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
101 |
-
pointHitDetectionRadius : 20,
|
102 |
-
|
103 |
-
//Boolean - Whether to show a stroke for datasets
|
104 |
-
datasetStroke : true,
|
105 |
-
|
106 |
-
//Number - Pixel width of dataset stroke
|
107 |
-
datasetStrokeWidth : 2,
|
108 |
-
|
109 |
-
//Boolean - Whether to fill the dataset with a colour
|
110 |
-
datasetFill : true,
|
111 |
-
{% raw %}
|
112 |
-
//String - A legend template
|
113 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].lineColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
114 |
-
{% endraw %}
|
115 |
-
}
|
116 |
-
```
|
117 |
-
|
118 |
-
|
119 |
-
You can override these for your `Chart` instance by passing a second argument into the `Radar` method as an object with the keys you want to override.
|
120 |
-
|
121 |
-
For example, we could have a radar chart without a point for each on piece of data by doing the following:
|
122 |
-
|
123 |
-
```javascript
|
124 |
-
new Chart(ctx).Radar(data, {
|
125 |
-
pointDot: false
|
126 |
-
});
|
127 |
-
// This will create a chart with all of the default options, merged from the global config,
|
128 |
-
// and the Bar chart defaults but this particular instance will have `pointDot` set to false.
|
129 |
-
```
|
130 |
-
|
131 |
-
We can also change these defaults values for each Radar type that is created, this object is available at `Chart.defaults.Radar`.
|
132 |
-
|
133 |
-
|
134 |
-
### Prototype methods
|
135 |
-
|
136 |
-
#### .getPointsAtEvent( event )
|
137 |
-
|
138 |
-
Calling `getPointsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the point elements that are at that the same position of that event.
|
139 |
-
|
140 |
-
```javascript
|
141 |
-
canvas.onclick = function(evt){
|
142 |
-
var activePoints = myRadarChart.getPointsAtEvent(evt);
|
143 |
-
// => activePoints is an array of points on the canvas that are at the same position as the click event.
|
144 |
-
};
|
145 |
-
```
|
146 |
-
|
147 |
-
This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
|
148 |
-
|
149 |
-
#### .update( )
|
150 |
-
|
151 |
-
Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop.
|
152 |
-
|
153 |
-
```javascript
|
154 |
-
myRadarChart.datasets[0].points[2].value = 50;
|
155 |
-
// Would update the first dataset's value of 'Sleeping' to be 50
|
156 |
-
myRadarChart.update();
|
157 |
-
// Calling update now animates the position of Sleeping from 90 to 50.
|
158 |
-
```
|
159 |
-
|
160 |
-
#### .addData( valuesArray, label )
|
161 |
-
|
162 |
-
Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those points.
|
163 |
-
|
164 |
-
```javascript
|
165 |
-
// The values array passed into addData should be one for each dataset in the chart
|
166 |
-
myRadarChart.addData([40, 60], "Dancing");
|
167 |
-
// The new data will now animate at the end of the chart.
|
168 |
-
```
|
169 |
-
|
170 |
-
#### .removeData( )
|
171 |
-
|
172 |
-
Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart.
|
173 |
-
|
174 |
-
```javascript
|
175 |
-
myRadarChart.removeData();
|
176 |
-
// Other points will now animate to their correct positions.
|
177 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/docs/04-Polar-Area-Chart.md
DELETED
@@ -1,172 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Polar Area Chart
|
3 |
-
anchor: polar-area-chart
|
4 |
-
---
|
5 |
-
### Introduction
|
6 |
-
Polar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value.
|
7 |
-
|
8 |
-
This type of chart is often useful when we want to show a comparison data similar to a pie chart, but also show a scale of values for context.
|
9 |
-
|
10 |
-
<div class="canvas-holder">
|
11 |
-
<canvas width="250" height="125"></canvas>
|
12 |
-
</div>
|
13 |
-
|
14 |
-
### Example usage
|
15 |
-
|
16 |
-
```javascript
|
17 |
-
new Chart(ctx).PolarArea(data, options);
|
18 |
-
```
|
19 |
-
|
20 |
-
### Data structure
|
21 |
-
|
22 |
-
```javascript
|
23 |
-
var data = [
|
24 |
-
{
|
25 |
-
value: 300,
|
26 |
-
color:"#F7464A",
|
27 |
-
highlight: "#FF5A5E",
|
28 |
-
label: "Red"
|
29 |
-
},
|
30 |
-
{
|
31 |
-
value: 50,
|
32 |
-
color: "#46BFBD",
|
33 |
-
highlight: "#5AD3D1",
|
34 |
-
label: "Green"
|
35 |
-
},
|
36 |
-
{
|
37 |
-
value: 100,
|
38 |
-
color: "#FDB45C",
|
39 |
-
highlight: "#FFC870",
|
40 |
-
label: "Yellow"
|
41 |
-
},
|
42 |
-
{
|
43 |
-
value: 40,
|
44 |
-
color: "#949FB1",
|
45 |
-
highlight: "#A8B3C5",
|
46 |
-
label: "Grey"
|
47 |
-
},
|
48 |
-
{
|
49 |
-
value: 120,
|
50 |
-
color: "#4D5360",
|
51 |
-
highlight: "#616774",
|
52 |
-
label: "Dark Grey"
|
53 |
-
}
|
54 |
-
|
55 |
-
];
|
56 |
-
```
|
57 |
-
As you can see, for the chart data you pass in an array of objects, with a value and a colour. The value attribute should be a number, while the color attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
|
58 |
-
|
59 |
-
### Chart options
|
60 |
-
|
61 |
-
These are the customisation options specific to Polar Area charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
|
62 |
-
|
63 |
-
```javascript
|
64 |
-
{
|
65 |
-
//Boolean - Show a backdrop to the scale label
|
66 |
-
scaleShowLabelBackdrop : true,
|
67 |
-
|
68 |
-
//String - The colour of the label backdrop
|
69 |
-
scaleBackdropColor : "rgba(255,255,255,0.75)",
|
70 |
-
|
71 |
-
// Boolean - Whether the scale should begin at zero
|
72 |
-
scaleBeginAtZero : true,
|
73 |
-
|
74 |
-
//Number - The backdrop padding above & below the label in pixels
|
75 |
-
scaleBackdropPaddingY : 2,
|
76 |
-
|
77 |
-
//Number - The backdrop padding to the side of the label in pixels
|
78 |
-
scaleBackdropPaddingX : 2,
|
79 |
-
|
80 |
-
//Boolean - Show line for each value in the scale
|
81 |
-
scaleShowLine : true,
|
82 |
-
|
83 |
-
//Boolean - Stroke a line around each segment in the chart
|
84 |
-
segmentShowStroke : true,
|
85 |
-
|
86 |
-
//String - The colour of the stroke on each segement.
|
87 |
-
segmentStrokeColor : "#fff",
|
88 |
-
|
89 |
-
//Number - The width of the stroke value in pixels
|
90 |
-
segmentStrokeWidth : 2,
|
91 |
-
|
92 |
-
//Number - Amount of animation steps
|
93 |
-
animationSteps : 100,
|
94 |
-
|
95 |
-
//String - Animation easing effect.
|
96 |
-
animationEasing : "easeOutBounce",
|
97 |
-
|
98 |
-
//Boolean - Whether to animate the rotation of the chart
|
99 |
-
animateRotate : true,
|
100 |
-
|
101 |
-
//Boolean - Whether to animate scaling the chart from the centre
|
102 |
-
animateScale : false,
|
103 |
-
{% raw %}
|
104 |
-
//String - A legend template
|
105 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
|
106 |
-
{% endraw %}
|
107 |
-
}
|
108 |
-
```
|
109 |
-
|
110 |
-
You can override these for your `Chart` instance by passing a second argument into the `PolarArea` method as an object with the keys you want to override.
|
111 |
-
|
112 |
-
For example, we could have a polar area chart with a black stroke on each segment like so:
|
113 |
-
|
114 |
-
```javascript
|
115 |
-
new Chart(ctx).PolarArea(data, {
|
116 |
-
segmentStrokeColor: "#000000"
|
117 |
-
});
|
118 |
-
// This will create a chart with all of the default options, merged from the global config,
|
119 |
-
// and the PolarArea chart defaults but this particular instance will have `segmentStrokeColor` set to `"#000000"`.
|
120 |
-
```
|
121 |
-
|
122 |
-
We can also change these defaults values for each PolarArea type that is created, this object is available at `Chart.defaults.PolarArea`.
|
123 |
-
|
124 |
-
### Prototype methods
|
125 |
-
|
126 |
-
#### .getSegmentsAtEvent( event )
|
127 |
-
|
128 |
-
Calling `getSegmentsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the segment elements that are at that the same position of that event.
|
129 |
-
|
130 |
-
```javascript
|
131 |
-
canvas.onclick = function(evt){
|
132 |
-
var activePoints = myPolarAreaChart.getSegmentsAtEvent(evt);
|
133 |
-
// => activePoints is an array of segments on the canvas that are at the same position as the click event.
|
134 |
-
};
|
135 |
-
```
|
136 |
-
|
137 |
-
This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
|
138 |
-
|
139 |
-
#### .update( )
|
140 |
-
|
141 |
-
Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop.
|
142 |
-
|
143 |
-
```javascript
|
144 |
-
myPolarAreaChart.segments[1].value = 10;
|
145 |
-
// Would update the first dataset's value of 'Green' to be 10
|
146 |
-
myPolarAreaChart.update();
|
147 |
-
// Calling update now animates the position of Green from 50 to 10.
|
148 |
-
```
|
149 |
-
|
150 |
-
#### .addData( segmentData, index )
|
151 |
-
|
152 |
-
Calling `addData(segmentData, index)` on your Chart instance passing an object in the same format as in the constructor. There is an option second argument of 'index', this determines at what index the new segment should be inserted into the chart.
|
153 |
-
|
154 |
-
```javascript
|
155 |
-
// An object in the same format as the original data source
|
156 |
-
myPolarAreaChart.addData({
|
157 |
-
value: 130,
|
158 |
-
color: "#B48EAD",
|
159 |
-
highlight: "#C69CBE",
|
160 |
-
label: "Purple"
|
161 |
-
});
|
162 |
-
// The new segment will now animate in.
|
163 |
-
```
|
164 |
-
|
165 |
-
#### .removeData( index )
|
166 |
-
|
167 |
-
Calling `removeData(index)` on your Chart instance will remove segment at that particular index. If none is provided, it will default to the last segment.
|
168 |
-
|
169 |
-
```javascript
|
170 |
-
myPolarAreaChart.removeData();
|
171 |
-
// Other segments will update to fill the empty space left.
|
172 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/docs/05-Pie-Doughnut-Chart.md
DELETED
@@ -1,158 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Pie & Doughnut Charts
|
3 |
-
anchor: doughnut-pie-chart
|
4 |
-
---
|
5 |
-
###Introduction
|
6 |
-
Pie and doughnut charts are probably the most commonly used chart there are. They are divided into segments, the arc of each segment shows the proportional value of each piece of data.
|
7 |
-
|
8 |
-
They are excellent at showing the relational proportions between data.
|
9 |
-
|
10 |
-
Pie and doughnut charts are effectively the same class in Chart.js, but have one different default value - their `percentageInnerCutout`. This equates what percentage of the inner should be cut out. This defaults to `0` for pie charts, and `50` for doughnuts.
|
11 |
-
|
12 |
-
They are also registered under two aliases in the `Chart` core. Other than their different default value, and different alias, they are exactly the same.
|
13 |
-
|
14 |
-
<div class="canvas-holder half">
|
15 |
-
<canvas width="250" height="125"></canvas>
|
16 |
-
</div>
|
17 |
-
|
18 |
-
<div class="canvas-holder half">
|
19 |
-
<canvas width="250" height="125"></canvas>
|
20 |
-
</div>
|
21 |
-
|
22 |
-
|
23 |
-
### Example usage
|
24 |
-
|
25 |
-
```javascript
|
26 |
-
// For a pie chart
|
27 |
-
var myPieChart = new Chart(ctx[0]).Pie(data,options);
|
28 |
-
|
29 |
-
// And for a doughnut chart
|
30 |
-
var myDoughnutChart = new Chart(ctx[1]).Doughnut(data,options);
|
31 |
-
```
|
32 |
-
|
33 |
-
### Data structure
|
34 |
-
|
35 |
-
```javascript
|
36 |
-
var data = [
|
37 |
-
{
|
38 |
-
value: 300,
|
39 |
-
color:"#F7464A",
|
40 |
-
highlight: "#FF5A5E",
|
41 |
-
label: "Red"
|
42 |
-
},
|
43 |
-
{
|
44 |
-
value: 50,
|
45 |
-
color: "#46BFBD",
|
46 |
-
highlight: "#5AD3D1",
|
47 |
-
label: "Green"
|
48 |
-
},
|
49 |
-
{
|
50 |
-
value: 100,
|
51 |
-
color: "#FDB45C",
|
52 |
-
highlight: "#FFC870",
|
53 |
-
label: "Yellow"
|
54 |
-
}
|
55 |
-
]
|
56 |
-
```
|
57 |
-
|
58 |
-
For a pie chart, you must pass in an array of objects with a value and a color property. The value attribute should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each. The color attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
|
59 |
-
|
60 |
-
### Chart options
|
61 |
-
|
62 |
-
These are the customisation options specific to Pie & Doughnut charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
|
63 |
-
|
64 |
-
```javascript
|
65 |
-
{
|
66 |
-
//Boolean - Whether we should show a stroke on each segment
|
67 |
-
segmentShowStroke : true,
|
68 |
-
|
69 |
-
//String - The colour of each segment stroke
|
70 |
-
segmentStrokeColor : "#fff",
|
71 |
-
|
72 |
-
//Number - The width of each segment stroke
|
73 |
-
segmentStrokeWidth : 2,
|
74 |
-
|
75 |
-
//Number - The percentage of the chart that we cut out of the middle
|
76 |
-
percentageInnerCutout : 50, // This is 0 for Pie charts
|
77 |
-
|
78 |
-
//Number - Amount of animation steps
|
79 |
-
animationSteps : 100,
|
80 |
-
|
81 |
-
//String - Animation easing effect
|
82 |
-
animationEasing : "easeOutBounce",
|
83 |
-
|
84 |
-
//Boolean - Whether we animate the rotation of the Doughnut
|
85 |
-
animateRotate : true,
|
86 |
-
|
87 |
-
//Boolean - Whether we animate scaling the Doughnut from the centre
|
88 |
-
animateScale : false,
|
89 |
-
{% raw %}
|
90 |
-
//String - A legend template
|
91 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
|
92 |
-
{% endraw %}
|
93 |
-
}
|
94 |
-
```
|
95 |
-
You can override these for your `Chart` instance by passing a second argument into the `Doughnut` method as an object with the keys you want to override.
|
96 |
-
|
97 |
-
For example, we could have a doughnut chart that animates by scaling out from the centre like so:
|
98 |
-
|
99 |
-
```javascript
|
100 |
-
new Chart(ctx).Doughnut(data, {
|
101 |
-
animateScale: true
|
102 |
-
});
|
103 |
-
// This will create a chart with all of the default options, merged from the global config,
|
104 |
-
// and the Doughnut chart defaults but this particular instance will have `animateScale` set to `true`.
|
105 |
-
```
|
106 |
-
|
107 |
-
We can also change these default values for each Doughnut type that is created, this object is available at `Chart.defaults.Doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.defaults.Pie`, with the only difference being `percentageInnerCutout` being set to 0.
|
108 |
-
|
109 |
-
### Prototype methods
|
110 |
-
|
111 |
-
#### .getSegmentsAtEvent( event )
|
112 |
-
|
113 |
-
Calling `getSegmentsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the segment elements that are at the same position of that event.
|
114 |
-
|
115 |
-
```javascript
|
116 |
-
canvas.onclick = function(evt){
|
117 |
-
var activePoints = myDoughnutChart.getSegmentsAtEvent(evt);
|
118 |
-
// => activePoints is an array of segments on the canvas that are at the same position as the click event.
|
119 |
-
};
|
120 |
-
```
|
121 |
-
|
122 |
-
This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
|
123 |
-
|
124 |
-
#### .update( )
|
125 |
-
|
126 |
-
Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop.
|
127 |
-
|
128 |
-
```javascript
|
129 |
-
myDoughnutChart.segments[1].value = 10;
|
130 |
-
// Would update the first dataset's value of 'Green' to be 10
|
131 |
-
myDoughnutChart.update();
|
132 |
-
// Calling update now animates the circumference of the segment 'Green' from 50 to 10.
|
133 |
-
// and transitions other segment widths
|
134 |
-
```
|
135 |
-
|
136 |
-
#### .addData( segmentData, index )
|
137 |
-
|
138 |
-
Calling `addData(segmentData, index)` on your Chart instance passing an object in the same format as in the constructor. There is an optional second argument of 'index', this determines at what index the new segment should be inserted into the chart.
|
139 |
-
|
140 |
-
```javascript
|
141 |
-
// An object in the same format as the original data source
|
142 |
-
myDoughnutChart.addData({
|
143 |
-
value: 130,
|
144 |
-
color: "#B48EAD",
|
145 |
-
highlight: "#C69CBE",
|
146 |
-
label: "Purple"
|
147 |
-
});
|
148 |
-
// The new segment will now animate in.
|
149 |
-
```
|
150 |
-
|
151 |
-
#### .removeData( index )
|
152 |
-
|
153 |
-
Calling `removeData(index)` on your Chart instance will remove segment at that particular index. If none is provided, it will default to the last segment.
|
154 |
-
|
155 |
-
```javascript
|
156 |
-
myDoughnutChart.removeData();
|
157 |
-
// Other segments will update to fill the empty space left.
|
158 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/docs/06-Advanced.md
DELETED
@@ -1,152 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Advanced usage
|
3 |
-
anchor: advanced-usage
|
4 |
-
---
|
5 |
-
|
6 |
-
|
7 |
-
### Prototype methods
|
8 |
-
|
9 |
-
For each chart, there are a set of global prototype methods on the shared `ChartType` which you may find useful. These are available on all charts created with Chart.js, but for the examples, let's use a line chart we've made.
|
10 |
-
|
11 |
-
```javascript
|
12 |
-
// For example:
|
13 |
-
var myLineChart = new Chart(ctx).Line(data);
|
14 |
-
```
|
15 |
-
|
16 |
-
#### .clear()
|
17 |
-
|
18 |
-
Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
|
19 |
-
|
20 |
-
```javascript
|
21 |
-
// Will clear the canvas that myLineChart is drawn on
|
22 |
-
myLineChart.clear();
|
23 |
-
// => returns 'this' for chainability
|
24 |
-
```
|
25 |
-
|
26 |
-
#### .stop()
|
27 |
-
|
28 |
-
Use this to stop any current animation loop. This will pause the chart during any current animation frame. Call `.render()` to re-animate.
|
29 |
-
|
30 |
-
```javascript
|
31 |
-
// Stops the charts animation loop at its current frame
|
32 |
-
myLineChart.stop();
|
33 |
-
// => returns 'this' for chainability
|
34 |
-
```
|
35 |
-
|
36 |
-
#### .resize()
|
37 |
-
|
38 |
-
Use this to manually resize the canvas element. This is run each time the browser is resized, but you can call this method manually if you change the size of the canvas nodes container element.
|
39 |
-
|
40 |
-
```javascript
|
41 |
-
// Resizes & redraws to fill its container element
|
42 |
-
myLineChart.resize();
|
43 |
-
// => returns 'this' for chainability
|
44 |
-
```
|
45 |
-
|
46 |
-
#### .destroy()
|
47 |
-
|
48 |
-
Use this to destroy any chart instances that are created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js.
|
49 |
-
|
50 |
-
```javascript
|
51 |
-
// Destroys a specific chart instance
|
52 |
-
myLineChart.destroy();
|
53 |
-
```
|
54 |
-
|
55 |
-
#### .toBase64Image()
|
56 |
-
|
57 |
-
This returns a base 64 encoded string of the chart in it's current state.
|
58 |
-
|
59 |
-
```javascript
|
60 |
-
myLineChart.toBase64Image();
|
61 |
-
// => returns png data url of the image on the canvas
|
62 |
-
```
|
63 |
-
|
64 |
-
#### .generateLegend()
|
65 |
-
|
66 |
-
Returns an HTML string of a legend for that chart. The template for this legend is at `legendTemplate` in the chart options.
|
67 |
-
|
68 |
-
```javascript
|
69 |
-
myLineChart.generateLegend();
|
70 |
-
// => returns HTML string of a legend for this chart
|
71 |
-
```
|
72 |
-
|
73 |
-
### Writing new chart types
|
74 |
-
|
75 |
-
Chart.js 1.0 has been rewritten to provide a platform for developers to create their own custom chart types, and be able to share and utilise them through the Chart.js API.
|
76 |
-
|
77 |
-
The format is relatively simple, there are a set of utility helper methods under `Chart.helpers`, including things such as looping over collections, requesting animation frames, and easing equations.
|
78 |
-
|
79 |
-
On top of this, there are also some simple base classes of Chart elements, these all extend from `Chart.Element`, and include things such as points, bars and scales.
|
80 |
-
|
81 |
-
```javascript
|
82 |
-
Chart.Type.extend({
|
83 |
-
// Passing in a name registers this chart in the Chart namespace
|
84 |
-
name: "Scatter",
|
85 |
-
// Providing a defaults will also register the deafults in the chart namespace
|
86 |
-
defaults : {
|
87 |
-
options: "Here",
|
88 |
-
available: "at this.options"
|
89 |
-
},
|
90 |
-
// Initialize is fired when the chart is initialized - Data is passed in as a parameter
|
91 |
-
// Config is automatically merged by the core of Chart.js, and is available at this.options
|
92 |
-
initialize: function(data){
|
93 |
-
this.chart.ctx // The drawing context for this chart
|
94 |
-
this.chart.canvas // the canvas node for this chart
|
95 |
-
},
|
96 |
-
// Used to draw something on the canvas
|
97 |
-
draw: function() {
|
98 |
-
}
|
99 |
-
});
|
100 |
-
|
101 |
-
// Now we can create a new instance of our chart, using the Chart.js API
|
102 |
-
new Chart(ctx).Scatter(data);
|
103 |
-
// initialize is now run
|
104 |
-
```
|
105 |
-
|
106 |
-
### Extending existing chart types
|
107 |
-
|
108 |
-
We can also extend existing chart types, and expose them to the API in the same way. Let's say for example, we might want to run some more code when we initialize every Line chart.
|
109 |
-
|
110 |
-
```javascript
|
111 |
-
// Notice now we're extending the particular Line chart type, rather than the base class.
|
112 |
-
Chart.types.Line.extend({
|
113 |
-
// Passing in a name registers this chart in the Chart namespace in the same way
|
114 |
-
name: "LineAlt",
|
115 |
-
initialize: function(data){
|
116 |
-
console.log('My Line chart extension');
|
117 |
-
Chart.types.Line.prototype.initialize.apply(this, arguments);
|
118 |
-
}
|
119 |
-
});
|
120 |
-
|
121 |
-
// Creates a line chart in the same way
|
122 |
-
new Chart(ctx).LineAlt(data);
|
123 |
-
// but this logs 'My Line chart extension' in the console.
|
124 |
-
```
|
125 |
-
|
126 |
-
### Community extensions
|
127 |
-
|
128 |
-
- <a href="https://github.com/Regaddi/Chart.StackedBar.js" target"_blank">Stacked Bar Chart</a> by <a href="https://twitter.com/Regaddi" target="_blank">@Regaddi</a>
|
129 |
-
- <a href="https://github.com/CAYdenberg/Chart.js" target"_blank">Error bars (bar and line charts)</a> by <a href="https://twitter.com/CAYdenberg" target="_blank">@CAYdenberg</a>
|
130 |
-
|
131 |
-
### Creating custom builds
|
132 |
-
|
133 |
-
Chart.js uses <a href="http://gulpjs.com/" target="_blank">gulp</a> to build the library into a single JavaScript file. We can use this same build script with custom parameters in order to build a custom version.
|
134 |
-
|
135 |
-
Firstly, we need to ensure development dependencies are installed. With node and npm installed, after cloning the Chart.js repo to a local directory, and navigating to that directory in the command line, we can run the following:
|
136 |
-
|
137 |
-
```bash
|
138 |
-
npm install
|
139 |
-
npm install -g gulp
|
140 |
-
```
|
141 |
-
|
142 |
-
This will install the local development dependencies for Chart.js, along with a CLI for the JavaScript task runner <a href="http://gulpjs.com/" target="_blank">gulp</a>.
|
143 |
-
|
144 |
-
Now, we can run the `gulp build` task, and pass in a comma seperated list of types as an argument to build a custom version of Chart.js with only specified chart types.
|
145 |
-
|
146 |
-
Here we will create a version of Chart.js with only Line, Radar and Bar charts included:
|
147 |
-
|
148 |
-
```bash
|
149 |
-
gulp build --types=Line,Radar,Bar
|
150 |
-
```
|
151 |
-
|
152 |
-
This will output to the `/custom` directory, and write two files, Chart.js, and Chart.min.js with only those chart types included.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/docs/07-Notes.md
DELETED
@@ -1,42 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Notes
|
3 |
-
anchor: notes
|
4 |
-
---
|
5 |
-
|
6 |
-
### Browser support
|
7 |
-
Browser support for the canvas element is available in all modern & major mobile browsers <a href="http://caniuse.com/canvas" target="_blank">(caniuse.com/canvas)</a>.
|
8 |
-
|
9 |
-
For IE8 & below, I would recommend using the polyfill ExplorerCanvas - available at <a href="https://code.google.com/p/explorercanvas/" target="_blank">https://code.google.com/p/explorercanvas/</a>. It falls back to Internet explorer's format VML when canvas support is not available. Example use:
|
10 |
-
|
11 |
-
```html
|
12 |
-
<head>
|
13 |
-
<!--[if lte IE 8]>
|
14 |
-
<script src="excanvas.js"></script>
|
15 |
-
<![endif]-->
|
16 |
-
</head>
|
17 |
-
```
|
18 |
-
|
19 |
-
Usually I would recommend feature detection to choose whether or not to load a polyfill, rather than IE conditional comments, however in this case, VML is a Microsoft proprietary format, so it will only work in IE.
|
20 |
-
|
21 |
-
Some important points to note in my experience using ExplorerCanvas as a fallback.
|
22 |
-
|
23 |
-
- Initialise charts on load rather than DOMContentReady when using the library, as sometimes a race condition will occur, and it will result in an error when trying to get the 2d context of a canvas.
|
24 |
-
- New VML DOM elements are being created for each animation frame and there is no hardware acceleration. As a result animation is usually slow and jerky, with flashing text. It is a good idea to dynamically turn off animation based on canvas support. I recommend using the excellent <a href="http://modernizr.com/" target="_blank">Modernizr</a> to do this.
|
25 |
-
- When declaring fonts, the library explorercanvas requires the font name to be in single quotes inside the string. For example, instead of your scaleFontFamily property being simply "Arial", explorercanvas support, use "'Arial'" instead. Chart.js does this for default values.
|
26 |
-
|
27 |
-
### Bugs & issues
|
28 |
-
|
29 |
-
Please report these on the GitHub page - at <a href="https://github.com/nnnick/Chart.js" target="_blank">github.com/nnnick/Chart.js</a>. If you could include a link to a simple <a href="http://jsbin.com/" target="_blank">jsbin</a> or similar to demonstrate the issue, that'd be really helpful.
|
30 |
-
|
31 |
-
|
32 |
-
### Contributing
|
33 |
-
New contributions to the library are welcome, just a couple of guidelines:
|
34 |
-
|
35 |
-
- Tabs for indentation, not spaces please.
|
36 |
-
- Please ensure you're changing the individual files in `/src`, not the concatenated output in the `Chart.js` file in the root of the repo.
|
37 |
-
- Please check that your code will pass `jshint` code standards, `gulp jshint` will run this for you.
|
38 |
-
- Please keep pull requests concise, and document new functionality in the relevant `.md` file.
|
39 |
-
- Consider whether your changes are useful for all users, or if creating a Chart.js extension would be more appropriate.
|
40 |
-
|
41 |
-
### License
|
42 |
-
Chart.js is open source and available under the <a href="http://opensource.org/licenses/MIT" target="_blank">MIT license</a>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/gulpfile.js
DELETED
@@ -1,131 +0,0 @@
|
|
1 |
-
var gulp = require('gulp'),
|
2 |
-
concat = require('gulp-concat'),
|
3 |
-
uglify = require('gulp-uglify'),
|
4 |
-
util = require('gulp-util'),
|
5 |
-
jshint = require('gulp-jshint'),
|
6 |
-
size = require('gulp-size'),
|
7 |
-
connect = require('gulp-connect'),
|
8 |
-
replace = require('gulp-replace'),
|
9 |
-
inquirer = require('inquirer'),
|
10 |
-
semver = require('semver'),
|
11 |
-
exec = require('child_process').exec,
|
12 |
-
fs = require('fs'),
|
13 |
-
package = require('./package.json'),
|
14 |
-
bower = require('./bower.json');
|
15 |
-
|
16 |
-
var srcDir = './src/';
|
17 |
-
/*
|
18 |
-
* Usage : gulp build --types=Bar,Line,Doughnut
|
19 |
-
* Output: - A built Chart.js file with Core and types Bar, Line and Doughnut concatenated together
|
20 |
-
* - A minified version of this code, in Chart.min.js
|
21 |
-
*/
|
22 |
-
|
23 |
-
gulp.task('build', function(){
|
24 |
-
|
25 |
-
// Default to all of the chart types, with Chart.Core first
|
26 |
-
var srcFiles = [FileName('Core')],
|
27 |
-
isCustom = !!(util.env.types),
|
28 |
-
outputDir = (isCustom) ? 'custom' : '.';
|
29 |
-
if (isCustom){
|
30 |
-
util.env.types.split(',').forEach(function(type){ return srcFiles.push(FileName(type))});
|
31 |
-
}
|
32 |
-
else{
|
33 |
-
// Seems gulp-concat remove duplicates - nice!
|
34 |
-
// So we can use this to sort out dependency order - aka include Core first!
|
35 |
-
srcFiles.push(srcDir+'*');
|
36 |
-
}
|
37 |
-
|
38 |
-
return gulp.src(srcFiles)
|
39 |
-
.pipe(concat('Chart.js'))
|
40 |
-
.pipe(replace('{{ version }}', package.version))
|
41 |
-
.pipe(gulp.dest(outputDir))
|
42 |
-
.pipe(uglify({preserveComments:'some'}))
|
43 |
-
.pipe(concat('Chart.min.js'))
|
44 |
-
.pipe(gulp.dest(outputDir));
|
45 |
-
|
46 |
-
function FileName(moduleName){
|
47 |
-
return srcDir+'Chart.'+moduleName+'.js';
|
48 |
-
};
|
49 |
-
});
|
50 |
-
|
51 |
-
/*
|
52 |
-
* Usage : gulp bump
|
53 |
-
* Prompts: Version increment to bump
|
54 |
-
* Output: - New version number written into package.json & bower.json
|
55 |
-
*/
|
56 |
-
|
57 |
-
gulp.task('bump', function(complete){
|
58 |
-
util.log('Current version:', util.colors.cyan(package.version));
|
59 |
-
var choices = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].map(function(versionType){
|
60 |
-
return versionType + ' (v' + semver.inc(package.version, versionType) + ')';
|
61 |
-
});
|
62 |
-
inquirer.prompt({
|
63 |
-
type: 'list',
|
64 |
-
name: 'version',
|
65 |
-
message: 'What version update would you like?',
|
66 |
-
choices: choices
|
67 |
-
}, function(res){
|
68 |
-
var increment = res.version.split(' ')[0],
|
69 |
-
newVersion = semver.inc(package.version, increment);
|
70 |
-
|
71 |
-
// Set the new versions into the bower/package object
|
72 |
-
package.version = newVersion;
|
73 |
-
bower.version = newVersion;
|
74 |
-
|
75 |
-
// Write these to their own files, then build the output
|
76 |
-
fs.writeFileSync('package.json', JSON.stringify(package, null, 2));
|
77 |
-
fs.writeFileSync('bower.json', JSON.stringify(bower, null, 2));
|
78 |
-
|
79 |
-
complete();
|
80 |
-
});
|
81 |
-
});
|
82 |
-
|
83 |
-
gulp.task('release', ['build'], function(){
|
84 |
-
exec('git tag -a v' + package.version);
|
85 |
-
});
|
86 |
-
|
87 |
-
gulp.task('jshint', function(){
|
88 |
-
return gulp.src(srcDir + '*.js')
|
89 |
-
.pipe(jshint())
|
90 |
-
.pipe(jshint.reporter('default'));
|
91 |
-
});
|
92 |
-
|
93 |
-
gulp.task('library-size', function(){
|
94 |
-
return gulp.src('Chart.min.js')
|
95 |
-
.pipe(size({
|
96 |
-
gzip: true
|
97 |
-
}));
|
98 |
-
});
|
99 |
-
|
100 |
-
gulp.task('module-sizes', function(){
|
101 |
-
return gulp.src(srcDir + '*.js')
|
102 |
-
.pipe(uglify({preserveComments:'some'}))
|
103 |
-
.pipe(size({
|
104 |
-
showFiles: true,
|
105 |
-
gzip: true
|
106 |
-
}))
|
107 |
-
});
|
108 |
-
|
109 |
-
gulp.task('watch', function(){
|
110 |
-
gulp.watch('./src/*', ['build']);
|
111 |
-
});
|
112 |
-
|
113 |
-
gulp.task('test', ['jshint']);
|
114 |
-
|
115 |
-
gulp.task('size', ['library-size', 'module-sizes']);
|
116 |
-
|
117 |
-
gulp.task('default', ['build', 'watch']);
|
118 |
-
|
119 |
-
gulp.task('server', function(){
|
120 |
-
connect.server({
|
121 |
-
port: 8000,
|
122 |
-
});
|
123 |
-
});
|
124 |
-
|
125 |
-
// Convenience task for opening the project straight from the command line
|
126 |
-
gulp.task('_open', function(){
|
127 |
-
exec('open http://localhost:8000');
|
128 |
-
exec('subl .');
|
129 |
-
});
|
130 |
-
|
131 |
-
gulp.task('dev', ['server', 'default']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/package.json
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"name": "chart.js",
|
3 |
-
"homepage": "http://www.chartjs.org",
|
4 |
-
"description": "Simple HTML5 charts using the canvas element.",
|
5 |
-
"version": "1.0.1-beta.4",
|
6 |
-
"main": "Chart.js",
|
7 |
-
"repository": {
|
8 |
-
"type": "git",
|
9 |
-
"url": "https://github.com/nnnick/Chart.js.git"
|
10 |
-
},
|
11 |
-
"dependences": {},
|
12 |
-
"devDependencies": {
|
13 |
-
"gulp": "3.5.x",
|
14 |
-
"gulp-concat": "~2.1.x",
|
15 |
-
"gulp-connect": "~2.0.5",
|
16 |
-
"gulp-jshint": "~1.5.1",
|
17 |
-
"gulp-replace": "^0.4.0",
|
18 |
-
"gulp-size": "~0.4.0",
|
19 |
-
"gulp-uglify": "~0.2.x",
|
20 |
-
"gulp-util": "~2.2.x",
|
21 |
-
"inquirer": "^0.5.1",
|
22 |
-
"semver": "^3.0.1"
|
23 |
-
}
|
24 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/samples/bar.html
DELETED
@@ -1,48 +0,0 @@
|
|
1 |
-
<!doctype html>
|
2 |
-
<html>
|
3 |
-
<head>
|
4 |
-
<title>Bar Chart</title>
|
5 |
-
<script src="../Chart.js"></script>
|
6 |
-
</head>
|
7 |
-
<body>
|
8 |
-
<div style="width: 50%">
|
9 |
-
<canvas id="canvas" height="450" width="600"></canvas>
|
10 |
-
</div>
|
11 |
-
|
12 |
-
|
13 |
-
<script>
|
14 |
-
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
|
15 |
-
|
16 |
-
var barChartData = {
|
17 |
-
labels : ["January","February","March","April","May","June","July"],
|
18 |
-
datasets : [
|
19 |
-
{
|
20 |
-
showTooltips:true,
|
21 |
-
label: "My Second dataset",
|
22 |
-
fillColor : "rgba(220,220,220,0.5)",
|
23 |
-
strokeColor : "rgba(220,220,220,0.8)",
|
24 |
-
highlightFill: "rgba(220,220,220,0.75)",
|
25 |
-
highlightStroke: "rgba(220,220,220,1)",
|
26 |
-
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
|
27 |
-
},
|
28 |
-
{
|
29 |
-
label: "My Second dataset",
|
30 |
-
fillColor : "rgba(151,187,205,0.5)",
|
31 |
-
strokeColor : "rgba(151,187,205,0.8)",
|
32 |
-
highlightFill : "rgba(151,187,205,0.75)",
|
33 |
-
highlightStroke : "rgba(151,187,205,1)",
|
34 |
-
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
|
35 |
-
}
|
36 |
-
]
|
37 |
-
|
38 |
-
}
|
39 |
-
window.onload = function(){
|
40 |
-
var ctx = document.getElementById("canvas").getContext("2d");
|
41 |
-
window.myBar = new Chart(ctx).Bar(barChartData, {
|
42 |
-
responsive : true
|
43 |
-
});
|
44 |
-
}
|
45 |
-
|
46 |
-
</script>
|
47 |
-
</body>
|
48 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/samples/doughnut.html
DELETED
@@ -1,67 +0,0 @@
|
|
1 |
-
<!doctype html>
|
2 |
-
<html>
|
3 |
-
<head>
|
4 |
-
<title>Doughnut Chart</title>
|
5 |
-
<script src="../Chart.js"></script>
|
6 |
-
<style>
|
7 |
-
body{
|
8 |
-
padding: 0;
|
9 |
-
margin: 0;
|
10 |
-
}
|
11 |
-
#canvas-holder{
|
12 |
-
width:30%;
|
13 |
-
}
|
14 |
-
</style>
|
15 |
-
</head>
|
16 |
-
<body>
|
17 |
-
<div id="canvas-holder">
|
18 |
-
<canvas id="chart-area" width="500" height="500"/>
|
19 |
-
</div>
|
20 |
-
|
21 |
-
|
22 |
-
<script>
|
23 |
-
|
24 |
-
var doughnutData = [
|
25 |
-
{
|
26 |
-
value: 300,
|
27 |
-
color:"#F7464A",
|
28 |
-
highlight: "#FF5A5E",
|
29 |
-
label: "Red"
|
30 |
-
},
|
31 |
-
{
|
32 |
-
value: 50,
|
33 |
-
color: "#46BFBD",
|
34 |
-
highlight: "#5AD3D1",
|
35 |
-
label: "Green"
|
36 |
-
},
|
37 |
-
{
|
38 |
-
value: 100,
|
39 |
-
color: "#FDB45C",
|
40 |
-
highlight: "#FFC870",
|
41 |
-
label: "Yellow"
|
42 |
-
},
|
43 |
-
{
|
44 |
-
value: 40,
|
45 |
-
color: "#949FB1",
|
46 |
-
highlight: "#A8B3C5",
|
47 |
-
label: "Grey"
|
48 |
-
},
|
49 |
-
{
|
50 |
-
value: 120,
|
51 |
-
color: "#4D5360",
|
52 |
-
highlight: "#616774",
|
53 |
-
label: "Dark Grey"
|
54 |
-
}
|
55 |
-
|
56 |
-
];
|
57 |
-
|
58 |
-
window.onload = function(){
|
59 |
-
var ctx = document.getElementById("chart-area").getContext("2d");
|
60 |
-
window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {responsive : true});
|
61 |
-
};
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
</script>
|
66 |
-
</body>
|
67 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/samples/line.html
DELETED
@@ -1,54 +0,0 @@
|
|
1 |
-
<!doctype html>
|
2 |
-
<html>
|
3 |
-
<head>
|
4 |
-
<title>Line Chart</title>
|
5 |
-
<script src="../Chart.js"></script>
|
6 |
-
</head>
|
7 |
-
<body>
|
8 |
-
<div style="width:30%">
|
9 |
-
<div>
|
10 |
-
<canvas id="canvas" height="450" width="600"></canvas>
|
11 |
-
</div>
|
12 |
-
</div>
|
13 |
-
|
14 |
-
|
15 |
-
<script>
|
16 |
-
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
|
17 |
-
var lineChartData = {
|
18 |
-
labels : ["January","February","March","April","May","June","July"],
|
19 |
-
datasets : [
|
20 |
-
{
|
21 |
-
label: "My First dataset",
|
22 |
-
fillColor : "rgba(220,220,220,0.2)",
|
23 |
-
strokeColor : "rgba(220,220,220,1)",
|
24 |
-
pointColor : "rgba(220,220,220,1)",
|
25 |
-
pointStrokeColor : "#fff",
|
26 |
-
pointHighlightFill : "#fff",
|
27 |
-
pointHighlightStroke : "rgba(220,220,220,1)",
|
28 |
-
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
|
29 |
-
},
|
30 |
-
{
|
31 |
-
label: "My Second dataset",
|
32 |
-
fillColor : "rgba(151,187,205,0.2)",
|
33 |
-
strokeColor : "rgba(151,187,205,1)",
|
34 |
-
pointColor : "rgba(151,187,205,1)",
|
35 |
-
pointStrokeColor : "#fff",
|
36 |
-
pointHighlightFill : "#fff",
|
37 |
-
pointHighlightStroke : "rgba(151,187,205,1)",
|
38 |
-
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
|
39 |
-
}
|
40 |
-
]
|
41 |
-
|
42 |
-
}
|
43 |
-
|
44 |
-
window.onload = function(){
|
45 |
-
var ctx = document.getElementById("canvas").getContext("2d");
|
46 |
-
window.myLine = new Chart(ctx).Line(lineChartData, {
|
47 |
-
responsive: true
|
48 |
-
});
|
49 |
-
}
|
50 |
-
|
51 |
-
|
52 |
-
</script>
|
53 |
-
</body>
|
54 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/samples/pie.html
DELETED
@@ -1,58 +0,0 @@
|
|
1 |
-
<!doctype html>
|
2 |
-
<html>
|
3 |
-
<head>
|
4 |
-
<title>Pie Chart</title>
|
5 |
-
<script src="../Chart.js"></script>
|
6 |
-
</head>
|
7 |
-
<body>
|
8 |
-
<div id="canvas-holder">
|
9 |
-
<canvas id="chart-area" width="300" height="300"/>
|
10 |
-
</div>
|
11 |
-
|
12 |
-
|
13 |
-
<script>
|
14 |
-
|
15 |
-
var pieData = [
|
16 |
-
{
|
17 |
-
value: 300,
|
18 |
-
color:"#F7464A",
|
19 |
-
highlight: "#FF5A5E",
|
20 |
-
label: "Red"
|
21 |
-
},
|
22 |
-
{
|
23 |
-
value: 50,
|
24 |
-
color: "#46BFBD",
|
25 |
-
highlight: "#5AD3D1",
|
26 |
-
label: "Green"
|
27 |
-
},
|
28 |
-
{
|
29 |
-
value: 100,
|
30 |
-
color: "#FDB45C",
|
31 |
-
highlight: "#FFC870",
|
32 |
-
label: "Yellow"
|
33 |
-
},
|
34 |
-
{
|
35 |
-
value: 40,
|
36 |
-
color: "#949FB1",
|
37 |
-
highlight: "#A8B3C5",
|
38 |
-
label: "Grey"
|
39 |
-
},
|
40 |
-
{
|
41 |
-
value: 120,
|
42 |
-
color: "#4D5360",
|
43 |
-
highlight: "#616774",
|
44 |
-
label: "Dark Grey"
|
45 |
-
}
|
46 |
-
|
47 |
-
];
|
48 |
-
|
49 |
-
window.onload = function(){
|
50 |
-
var ctx = document.getElementById("chart-area").getContext("2d");
|
51 |
-
window.myPie = new Chart(ctx).Pie(pieData);
|
52 |
-
};
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
</script>
|
57 |
-
</body>
|
58 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/samples/polar-area.html
DELETED
@@ -1,60 +0,0 @@
|
|
1 |
-
<!doctype html>
|
2 |
-
<html>
|
3 |
-
<head>
|
4 |
-
<title>Polar Area Chart</title>
|
5 |
-
<script src="../Chart.js"></script>
|
6 |
-
</head>
|
7 |
-
<body>
|
8 |
-
<div id="canvas-holder" style="width:30%">
|
9 |
-
<canvas id="chart-area" width="300" height="300"/>
|
10 |
-
</div>
|
11 |
-
|
12 |
-
|
13 |
-
<script>
|
14 |
-
|
15 |
-
var polarData = [
|
16 |
-
{
|
17 |
-
value: 300,
|
18 |
-
color:"#F7464A",
|
19 |
-
highlight: "#FF5A5E",
|
20 |
-
label: "Red"
|
21 |
-
},
|
22 |
-
{
|
23 |
-
value: 50,
|
24 |
-
color: "#46BFBD",
|
25 |
-
highlight: "#5AD3D1",
|
26 |
-
label: "Green"
|
27 |
-
},
|
28 |
-
{
|
29 |
-
value: 100,
|
30 |
-
color: "#FDB45C",
|
31 |
-
highlight: "#FFC870",
|
32 |
-
label: "Yellow"
|
33 |
-
},
|
34 |
-
{
|
35 |
-
value: 40,
|
36 |
-
color: "#949FB1",
|
37 |
-
highlight: "#A8B3C5",
|
38 |
-
label: "Grey"
|
39 |
-
},
|
40 |
-
{
|
41 |
-
value: 120,
|
42 |
-
color: "#4D5360",
|
43 |
-
highlight: "#616774",
|
44 |
-
label: "Dark Grey"
|
45 |
-
}
|
46 |
-
|
47 |
-
];
|
48 |
-
|
49 |
-
window.onload = function(){
|
50 |
-
var ctx = document.getElementById("chart-area").getContext("2d");
|
51 |
-
window.myPolarArea = new Chart(ctx).PolarArea(polarData, {
|
52 |
-
responsive:true
|
53 |
-
});
|
54 |
-
};
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
</script>
|
59 |
-
</body>
|
60 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/samples/radar.html
DELETED
@@ -1,53 +0,0 @@
|
|
1 |
-
<!doctype html>
|
2 |
-
<html>
|
3 |
-
<head>
|
4 |
-
<title>Radar Chart</title>
|
5 |
-
<script src="../Chart.js"></script>
|
6 |
-
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
|
7 |
-
<style>
|
8 |
-
canvas{
|
9 |
-
}
|
10 |
-
</style>
|
11 |
-
</head>
|
12 |
-
<body>
|
13 |
-
<div style="width:30%">
|
14 |
-
<canvas id="canvas" height="450" width="450"></canvas>
|
15 |
-
</div>
|
16 |
-
|
17 |
-
|
18 |
-
<script>
|
19 |
-
var radarChartData = {
|
20 |
-
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
|
21 |
-
datasets: [
|
22 |
-
{
|
23 |
-
label: "My First dataset",
|
24 |
-
fillColor: "rgba(220,220,220,0.2)",
|
25 |
-
strokeColor: "rgba(220,220,220,1)",
|
26 |
-
pointColor: "rgba(220,220,220,1)",
|
27 |
-
pointStrokeColor: "#fff",
|
28 |
-
pointHighlightFill: "#fff",
|
29 |
-
pointHighlightStroke: "rgba(220,220,220,1)",
|
30 |
-
data: [65,59,90,81,56,55,40]
|
31 |
-
},
|
32 |
-
{
|
33 |
-
label: "My Second dataset",
|
34 |
-
fillColor: "rgba(151,187,205,0.2)",
|
35 |
-
strokeColor: "rgba(151,187,205,1)",
|
36 |
-
pointColor: "rgba(151,187,205,1)",
|
37 |
-
pointStrokeColor: "#fff",
|
38 |
-
pointHighlightFill: "#fff",
|
39 |
-
pointHighlightStroke: "rgba(151,187,205,1)",
|
40 |
-
data: [28,48,40,19,96,27,100]
|
41 |
-
}
|
42 |
-
]
|
43 |
-
};
|
44 |
-
|
45 |
-
window.onload = function(){
|
46 |
-
window.myRadar = new Chart(document.getElementById("canvas").getContext("2d")).Radar(radarChartData, {
|
47 |
-
responsive: true
|
48 |
-
});
|
49 |
-
}
|
50 |
-
|
51 |
-
</script>
|
52 |
-
</body>
|
53 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/src/Chart.Bar.js
DELETED
@@ -1,294 +0,0 @@
|
|
1 |
-
(function(){
|
2 |
-
"use strict";
|
3 |
-
|
4 |
-
var root = this,
|
5 |
-
Chart = root.Chart,
|
6 |
-
helpers = Chart.helpers;
|
7 |
-
|
8 |
-
|
9 |
-
var defaultConfig = {
|
10 |
-
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
|
11 |
-
scaleBeginAtZero : true,
|
12 |
-
|
13 |
-
//Boolean - Whether grid lines are shown across the chart
|
14 |
-
scaleShowGridLines : true,
|
15 |
-
|
16 |
-
//String - Colour of the grid lines
|
17 |
-
scaleGridLineColor : "rgba(0,0,0,.05)",
|
18 |
-
|
19 |
-
//Number - Width of the grid lines
|
20 |
-
scaleGridLineWidth : 1,
|
21 |
-
|
22 |
-
//Boolean - If there is a stroke on each bar
|
23 |
-
barShowStroke : true,
|
24 |
-
|
25 |
-
//Number - Pixel width of the bar stroke
|
26 |
-
barStrokeWidth : 2,
|
27 |
-
|
28 |
-
//Number - Spacing between each of the X value sets
|
29 |
-
barValueSpacing : 5,
|
30 |
-
|
31 |
-
//Number - Spacing between data sets within X values
|
32 |
-
barDatasetSpacing : 1,
|
33 |
-
|
34 |
-
//String - A legend template
|
35 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
36 |
-
|
37 |
-
};
|
38 |
-
|
39 |
-
|
40 |
-
Chart.Type.extend({
|
41 |
-
name: "Bar",
|
42 |
-
defaults : defaultConfig,
|
43 |
-
initialize: function(data){
|
44 |
-
|
45 |
-
//Expose options as a scope variable here so we can access it in the ScaleClass
|
46 |
-
var options = this.options;
|
47 |
-
|
48 |
-
this.ScaleClass = Chart.Scale.extend({
|
49 |
-
offsetGridLines : true,
|
50 |
-
calculateBarX : function(datasetCount, datasetIndex, barIndex){
|
51 |
-
//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
|
52 |
-
var xWidth = this.calculateBaseWidth(),
|
53 |
-
xAbsolute = this.calculateX(barIndex) - (xWidth/2),
|
54 |
-
barWidth = this.calculateBarWidth(datasetCount);
|
55 |
-
|
56 |
-
return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;
|
57 |
-
},
|
58 |
-
calculateBaseWidth : function(){
|
59 |
-
return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
|
60 |
-
},
|
61 |
-
calculateBarWidth : function(datasetCount){
|
62 |
-
//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
|
63 |
-
var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);
|
64 |
-
|
65 |
-
return (baseWidth / datasetCount);
|
66 |
-
}
|
67 |
-
});
|
68 |
-
|
69 |
-
this.datasets = [];
|
70 |
-
|
71 |
-
//Set up tooltip events on the chart
|
72 |
-
if (this.options.showTooltips){
|
73 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
74 |
-
var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
|
75 |
-
|
76 |
-
this.eachBars(function(bar){
|
77 |
-
bar.restore(['fillColor', 'strokeColor']);
|
78 |
-
});
|
79 |
-
helpers.each(activeBars, function(activeBar){
|
80 |
-
activeBar.fillColor = activeBar.highlightFill;
|
81 |
-
activeBar.strokeColor = activeBar.highlightStroke;
|
82 |
-
});
|
83 |
-
this.showTooltip(activeBars);
|
84 |
-
});
|
85 |
-
}
|
86 |
-
|
87 |
-
//Declare the extension of the default point, to cater for the options passed in to the constructor
|
88 |
-
this.BarClass = Chart.Rectangle.extend({
|
89 |
-
strokeWidth : this.options.barStrokeWidth,
|
90 |
-
showStroke : this.options.barShowStroke,
|
91 |
-
ctx : this.chart.ctx
|
92 |
-
});
|
93 |
-
|
94 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
95 |
-
helpers.each(data.datasets,function(dataset,datasetIndex){
|
96 |
-
|
97 |
-
var datasetObject = {
|
98 |
-
label : dataset.label || null,
|
99 |
-
fillColor : dataset.fillColor,
|
100 |
-
strokeColor : dataset.strokeColor,
|
101 |
-
bars : []
|
102 |
-
};
|
103 |
-
|
104 |
-
this.datasets.push(datasetObject);
|
105 |
-
|
106 |
-
helpers.each(dataset.data,function(dataPoint,index){
|
107 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
108 |
-
datasetObject.bars.push(new this.BarClass({
|
109 |
-
value : dataPoint,
|
110 |
-
label : data.labels[index],
|
111 |
-
datasetLabel: dataset.label,
|
112 |
-
strokeColor : dataset.strokeColor,
|
113 |
-
fillColor : dataset.fillColor,
|
114 |
-
highlightFill : dataset.highlightFill || dataset.fillColor,
|
115 |
-
highlightStroke : dataset.highlightStroke || dataset.strokeColor
|
116 |
-
}));
|
117 |
-
},this);
|
118 |
-
|
119 |
-
},this);
|
120 |
-
|
121 |
-
this.buildScale(data.labels);
|
122 |
-
|
123 |
-
this.BarClass.prototype.base = this.scale.endPoint;
|
124 |
-
|
125 |
-
this.eachBars(function(bar, index, datasetIndex){
|
126 |
-
helpers.extend(bar, {
|
127 |
-
width : this.scale.calculateBarWidth(this.datasets.length),
|
128 |
-
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
|
129 |
-
y: this.scale.endPoint
|
130 |
-
});
|
131 |
-
bar.save();
|
132 |
-
}, this);
|
133 |
-
|
134 |
-
this.render();
|
135 |
-
},
|
136 |
-
update : function(){
|
137 |
-
this.scale.update();
|
138 |
-
// Reset any highlight colours before updating.
|
139 |
-
helpers.each(this.activeElements, function(activeElement){
|
140 |
-
activeElement.restore(['fillColor', 'strokeColor']);
|
141 |
-
});
|
142 |
-
|
143 |
-
this.eachBars(function(bar){
|
144 |
-
bar.save();
|
145 |
-
});
|
146 |
-
this.render();
|
147 |
-
},
|
148 |
-
eachBars : function(callback){
|
149 |
-
helpers.each(this.datasets,function(dataset, datasetIndex){
|
150 |
-
helpers.each(dataset.bars, callback, this, datasetIndex);
|
151 |
-
},this);
|
152 |
-
},
|
153 |
-
getBarsAtEvent : function(e){
|
154 |
-
var barsArray = [],
|
155 |
-
eventPosition = helpers.getRelativePosition(e),
|
156 |
-
datasetIterator = function(dataset){
|
157 |
-
barsArray.push(dataset.bars[barIndex]);
|
158 |
-
},
|
159 |
-
barIndex;
|
160 |
-
|
161 |
-
for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
|
162 |
-
for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
|
163 |
-
if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
|
164 |
-
helpers.each(this.datasets, datasetIterator);
|
165 |
-
return barsArray;
|
166 |
-
}
|
167 |
-
}
|
168 |
-
}
|
169 |
-
|
170 |
-
return barsArray;
|
171 |
-
},
|
172 |
-
buildScale : function(labels){
|
173 |
-
var self = this;
|
174 |
-
|
175 |
-
var dataTotal = function(){
|
176 |
-
var values = [];
|
177 |
-
self.eachBars(function(bar){
|
178 |
-
values.push(bar.value);
|
179 |
-
});
|
180 |
-
return values;
|
181 |
-
};
|
182 |
-
|
183 |
-
var scaleOptions = {
|
184 |
-
templateString : this.options.scaleLabel,
|
185 |
-
height : this.chart.height,
|
186 |
-
width : this.chart.width,
|
187 |
-
ctx : this.chart.ctx,
|
188 |
-
textColor : this.options.scaleFontColor,
|
189 |
-
fontSize : this.options.scaleFontSize,
|
190 |
-
fontStyle : this.options.scaleFontStyle,
|
191 |
-
fontFamily : this.options.scaleFontFamily,
|
192 |
-
valuesCount : labels.length,
|
193 |
-
beginAtZero : this.options.scaleBeginAtZero,
|
194 |
-
integersOnly : this.options.scaleIntegersOnly,
|
195 |
-
calculateYRange: function(currentHeight){
|
196 |
-
var updatedRanges = helpers.calculateScaleRange(
|
197 |
-
dataTotal(),
|
198 |
-
currentHeight,
|
199 |
-
this.fontSize,
|
200 |
-
this.beginAtZero,
|
201 |
-
this.integersOnly
|
202 |
-
);
|
203 |
-
helpers.extend(this, updatedRanges);
|
204 |
-
},
|
205 |
-
xLabels : labels,
|
206 |
-
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
207 |
-
lineWidth : this.options.scaleLineWidth,
|
208 |
-
lineColor : this.options.scaleLineColor,
|
209 |
-
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
210 |
-
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
211 |
-
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
|
212 |
-
showLabels : this.options.scaleShowLabels,
|
213 |
-
display : this.options.showScale
|
214 |
-
};
|
215 |
-
|
216 |
-
if (this.options.scaleOverride){
|
217 |
-
helpers.extend(scaleOptions, {
|
218 |
-
calculateYRange: helpers.noop,
|
219 |
-
steps: this.options.scaleSteps,
|
220 |
-
stepValue: this.options.scaleStepWidth,
|
221 |
-
min: this.options.scaleStartValue,
|
222 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
223 |
-
});
|
224 |
-
}
|
225 |
-
|
226 |
-
this.scale = new this.ScaleClass(scaleOptions);
|
227 |
-
},
|
228 |
-
addData : function(valuesArray,label){
|
229 |
-
//Map the values array for each of the datasets
|
230 |
-
helpers.each(valuesArray,function(value,datasetIndex){
|
231 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
232 |
-
this.datasets[datasetIndex].bars.push(new this.BarClass({
|
233 |
-
value : value,
|
234 |
-
label : label,
|
235 |
-
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
|
236 |
-
y: this.scale.endPoint,
|
237 |
-
width : this.scale.calculateBarWidth(this.datasets.length),
|
238 |
-
base : this.scale.endPoint,
|
239 |
-
strokeColor : this.datasets[datasetIndex].strokeColor,
|
240 |
-
fillColor : this.datasets[datasetIndex].fillColor
|
241 |
-
}));
|
242 |
-
},this);
|
243 |
-
|
244 |
-
this.scale.addXLabel(label);
|
245 |
-
//Then re-render the chart.
|
246 |
-
this.update();
|
247 |
-
},
|
248 |
-
removeData : function(){
|
249 |
-
this.scale.removeXLabel();
|
250 |
-
//Then re-render the chart.
|
251 |
-
helpers.each(this.datasets,function(dataset){
|
252 |
-
dataset.bars.shift();
|
253 |
-
},this);
|
254 |
-
this.update();
|
255 |
-
},
|
256 |
-
reflow : function(){
|
257 |
-
helpers.extend(this.BarClass.prototype,{
|
258 |
-
y: this.scale.endPoint,
|
259 |
-
base : this.scale.endPoint
|
260 |
-
});
|
261 |
-
var newScaleProps = helpers.extend({
|
262 |
-
height : this.chart.height,
|
263 |
-
width : this.chart.width
|
264 |
-
});
|
265 |
-
this.scale.update(newScaleProps);
|
266 |
-
},
|
267 |
-
draw : function(ease){
|
268 |
-
var easingDecimal = ease || 1;
|
269 |
-
this.clear();
|
270 |
-
|
271 |
-
var ctx = this.chart.ctx;
|
272 |
-
|
273 |
-
this.scale.draw(easingDecimal);
|
274 |
-
|
275 |
-
//Draw all the bars for each dataset
|
276 |
-
helpers.each(this.datasets,function(dataset,datasetIndex){
|
277 |
-
helpers.each(dataset.bars,function(bar,index){
|
278 |
-
if (bar.hasValue()){
|
279 |
-
bar.base = this.scale.endPoint;
|
280 |
-
//Transition then draw
|
281 |
-
bar.transition({
|
282 |
-
x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
|
283 |
-
y : this.scale.calculateY(bar.value),
|
284 |
-
width : this.scale.calculateBarWidth(this.datasets.length)
|
285 |
-
}, easingDecimal).draw();
|
286 |
-
}
|
287 |
-
},this);
|
288 |
-
|
289 |
-
},this);
|
290 |
-
}
|
291 |
-
});
|
292 |
-
|
293 |
-
|
294 |
-
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/src/Chart.Core.js
DELETED
@@ -1,1943 +0,0 @@
|
|
1 |
-
/*!
|
2 |
-
* Chart.js
|
3 |
-
* http://chartjs.org/
|
4 |
-
* Version: {{ version }}
|
5 |
-
*
|
6 |
-
* Copyright 2014 Nick Downie
|
7 |
-
* Released under the MIT license
|
8 |
-
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
|
9 |
-
*/
|
10 |
-
|
11 |
-
|
12 |
-
(function(){
|
13 |
-
|
14 |
-
"use strict";
|
15 |
-
|
16 |
-
//Declare root variable - window in the browser, global on the server
|
17 |
-
var root = this,
|
18 |
-
previous = root.Chart;
|
19 |
-
|
20 |
-
//Occupy the global variable of Chart, and create a simple base class
|
21 |
-
var Chart = function(context){
|
22 |
-
var chart = this;
|
23 |
-
this.canvas = context.canvas;
|
24 |
-
|
25 |
-
this.ctx = context;
|
26 |
-
|
27 |
-
//Variables global to the chart
|
28 |
-
var width = this.width = context.canvas.width;
|
29 |
-
var height = this.height = context.canvas.height;
|
30 |
-
this.aspectRatio = this.width / this.height;
|
31 |
-
//High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
|
32 |
-
helpers.retinaScale(this);
|
33 |
-
|
34 |
-
return this;
|
35 |
-
};
|
36 |
-
//Globally expose the defaults to allow for user updating/changing
|
37 |
-
Chart.defaults = {
|
38 |
-
global: {
|
39 |
-
// Boolean - Whether to animate the chart
|
40 |
-
animation: true,
|
41 |
-
|
42 |
-
// Number - Number of animation steps
|
43 |
-
animationSteps: 60,
|
44 |
-
|
45 |
-
// String - Animation easing effect
|
46 |
-
animationEasing: "easeOutQuart",
|
47 |
-
|
48 |
-
// Boolean - If we should show the scale at all
|
49 |
-
showScale: true,
|
50 |
-
|
51 |
-
// Boolean - If we want to override with a hard coded scale
|
52 |
-
scaleOverride: false,
|
53 |
-
|
54 |
-
// ** Required if scaleOverride is true **
|
55 |
-
// Number - The number of steps in a hard coded scale
|
56 |
-
scaleSteps: null,
|
57 |
-
// Number - The value jump in the hard coded scale
|
58 |
-
scaleStepWidth: null,
|
59 |
-
// Number - The scale starting value
|
60 |
-
scaleStartValue: null,
|
61 |
-
|
62 |
-
// String - Colour of the scale line
|
63 |
-
scaleLineColor: "rgba(0,0,0,.1)",
|
64 |
-
|
65 |
-
// Number - Pixel width of the scale line
|
66 |
-
scaleLineWidth: 1,
|
67 |
-
|
68 |
-
// Boolean - Whether to show labels on the scale
|
69 |
-
scaleShowLabels: true,
|
70 |
-
|
71 |
-
// Interpolated JS string - can access value
|
72 |
-
scaleLabel: "<%=value%>",
|
73 |
-
|
74 |
-
// Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there
|
75 |
-
scaleIntegersOnly: true,
|
76 |
-
|
77 |
-
// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
|
78 |
-
scaleBeginAtZero: false,
|
79 |
-
|
80 |
-
// String - Scale label font declaration for the scale label
|
81 |
-
scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
82 |
-
|
83 |
-
// Number - Scale label font size in pixels
|
84 |
-
scaleFontSize: 12,
|
85 |
-
|
86 |
-
// String - Scale label font weight style
|
87 |
-
scaleFontStyle: "normal",
|
88 |
-
|
89 |
-
// String - Scale label font colour
|
90 |
-
scaleFontColor: "#666",
|
91 |
-
|
92 |
-
// Boolean - whether or not the chart should be responsive and resize when the browser does.
|
93 |
-
responsive: false,
|
94 |
-
|
95 |
-
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
|
96 |
-
maintainAspectRatio: true,
|
97 |
-
|
98 |
-
// Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove
|
99 |
-
showTooltips: true,
|
100 |
-
|
101 |
-
// Array - Array of string names to attach tooltip events
|
102 |
-
tooltipEvents: ["mousemove", "touchstart", "touchmove", "mouseout"],
|
103 |
-
|
104 |
-
// String - Tooltip background colour
|
105 |
-
tooltipFillColor: "rgba(0,0,0,0.8)",
|
106 |
-
|
107 |
-
// String - Tooltip label font declaration for the scale label
|
108 |
-
tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
109 |
-
|
110 |
-
// Number - Tooltip label font size in pixels
|
111 |
-
tooltipFontSize: 14,
|
112 |
-
|
113 |
-
// String - Tooltip font weight style
|
114 |
-
tooltipFontStyle: "normal",
|
115 |
-
|
116 |
-
// String - Tooltip label font colour
|
117 |
-
tooltipFontColor: "#fff",
|
118 |
-
|
119 |
-
// String - Tooltip title font declaration for the scale label
|
120 |
-
tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
121 |
-
|
122 |
-
// Number - Tooltip title font size in pixels
|
123 |
-
tooltipTitleFontSize: 14,
|
124 |
-
|
125 |
-
// String - Tooltip title font weight style
|
126 |
-
tooltipTitleFontStyle: "bold",
|
127 |
-
|
128 |
-
// String - Tooltip title font colour
|
129 |
-
tooltipTitleFontColor: "#fff",
|
130 |
-
|
131 |
-
// Number - pixel width of padding around tooltip text
|
132 |
-
tooltipYPadding: 6,
|
133 |
-
|
134 |
-
// Number - pixel width of padding around tooltip text
|
135 |
-
tooltipXPadding: 6,
|
136 |
-
|
137 |
-
// Number - Size of the caret on the tooltip
|
138 |
-
tooltipCaretSize: 8,
|
139 |
-
|
140 |
-
// Number - Pixel radius of the tooltip border
|
141 |
-
tooltipCornerRadius: 6,
|
142 |
-
|
143 |
-
// Number - Pixel offset from point x to tooltip edge
|
144 |
-
tooltipXOffset: 10,
|
145 |
-
|
146 |
-
// String - Template string for single tooltips
|
147 |
-
tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>",
|
148 |
-
|
149 |
-
// String - Template string for single tooltips
|
150 |
-
multiTooltipTemplate: "<%= value %>",
|
151 |
-
|
152 |
-
// String - Colour behind the legend colour block
|
153 |
-
multiTooltipKeyBackground: '#fff',
|
154 |
-
|
155 |
-
// Function - Will fire on animation progression.
|
156 |
-
onAnimationProgress: function(){},
|
157 |
-
|
158 |
-
// Function - Will fire on animation completion.
|
159 |
-
onAnimationComplete: function(){}
|
160 |
-
|
161 |
-
}
|
162 |
-
};
|
163 |
-
|
164 |
-
//Create a dictionary of chart types, to allow for extension of existing types
|
165 |
-
Chart.types = {};
|
166 |
-
|
167 |
-
//Global Chart helpers object for utility methods and classes
|
168 |
-
var helpers = Chart.helpers = {};
|
169 |
-
|
170 |
-
//-- Basic js utility methods
|
171 |
-
var each = helpers.each = function(loopable,callback,self){
|
172 |
-
var additionalArgs = Array.prototype.slice.call(arguments, 3);
|
173 |
-
// Check to see if null or undefined firstly.
|
174 |
-
if (loopable){
|
175 |
-
if (loopable.length === +loopable.length){
|
176 |
-
var i;
|
177 |
-
for (i=0; i<loopable.length; i++){
|
178 |
-
callback.apply(self,[loopable[i], i].concat(additionalArgs));
|
179 |
-
}
|
180 |
-
}
|
181 |
-
else{
|
182 |
-
for (var item in loopable){
|
183 |
-
callback.apply(self,[loopable[item],item].concat(additionalArgs));
|
184 |
-
}
|
185 |
-
}
|
186 |
-
}
|
187 |
-
},
|
188 |
-
clone = helpers.clone = function(obj){
|
189 |
-
var objClone = {};
|
190 |
-
each(obj,function(value,key){
|
191 |
-
if (obj.hasOwnProperty(key)) objClone[key] = value;
|
192 |
-
});
|
193 |
-
return objClone;
|
194 |
-
},
|
195 |
-
extend = helpers.extend = function(base){
|
196 |
-
each(Array.prototype.slice.call(arguments,1), function(extensionObject) {
|
197 |
-
each(extensionObject,function(value,key){
|
198 |
-
if (extensionObject.hasOwnProperty(key)) base[key] = value;
|
199 |
-
});
|
200 |
-
});
|
201 |
-
return base;
|
202 |
-
},
|
203 |
-
merge = helpers.merge = function(base,master){
|
204 |
-
//Merge properties in left object over to a shallow clone of object right.
|
205 |
-
var args = Array.prototype.slice.call(arguments,0);
|
206 |
-
args.unshift({});
|
207 |
-
return extend.apply(null, args);
|
208 |
-
},
|
209 |
-
indexOf = helpers.indexOf = function(arrayToSearch, item){
|
210 |
-
if (Array.prototype.indexOf) {
|
211 |
-
return arrayToSearch.indexOf(item);
|
212 |
-
}
|
213 |
-
else{
|
214 |
-
for (var i = 0; i < arrayToSearch.length; i++) {
|
215 |
-
if (arrayToSearch[i] === item) return i;
|
216 |
-
}
|
217 |
-
return -1;
|
218 |
-
}
|
219 |
-
},
|
220 |
-
where = helpers.where = function(collection, filterCallback){
|
221 |
-
var filtered = [];
|
222 |
-
|
223 |
-
helpers.each(collection, function(item){
|
224 |
-
if (filterCallback(item)){
|
225 |
-
filtered.push(item);
|
226 |
-
}
|
227 |
-
});
|
228 |
-
|
229 |
-
return filtered;
|
230 |
-
},
|
231 |
-
findNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex){
|
232 |
-
// Default to start of the array
|
233 |
-
if (!startIndex){
|
234 |
-
startIndex = -1;
|
235 |
-
}
|
236 |
-
for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
|
237 |
-
var currentItem = arrayToSearch[i];
|
238 |
-
if (filterCallback(currentItem)){
|
239 |
-
return currentItem;
|
240 |
-
}
|
241 |
-
};
|
242 |
-
},
|
243 |
-
findPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex){
|
244 |
-
// Default to end of the array
|
245 |
-
if (!startIndex){
|
246 |
-
startIndex = arrayToSearch.length;
|
247 |
-
}
|
248 |
-
for (var i = startIndex - 1; i >= 0; i--) {
|
249 |
-
var currentItem = arrayToSearch[i];
|
250 |
-
if (filterCallback(currentItem)){
|
251 |
-
return currentItem;
|
252 |
-
}
|
253 |
-
};
|
254 |
-
},
|
255 |
-
inherits = helpers.inherits = function(extensions){
|
256 |
-
//Basic javascript inheritance based on the model created in Backbone.js
|
257 |
-
var parent = this;
|
258 |
-
var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function(){ return parent.apply(this, arguments); };
|
259 |
-
|
260 |
-
var Surrogate = function(){ this.constructor = ChartElement;};
|
261 |
-
Surrogate.prototype = parent.prototype;
|
262 |
-
ChartElement.prototype = new Surrogate();
|
263 |
-
|
264 |
-
ChartElement.extend = inherits;
|
265 |
-
|
266 |
-
if (extensions) extend(ChartElement.prototype, extensions);
|
267 |
-
|
268 |
-
ChartElement.__super__ = parent.prototype;
|
269 |
-
|
270 |
-
return ChartElement;
|
271 |
-
},
|
272 |
-
noop = helpers.noop = function(){},
|
273 |
-
uid = helpers.uid = (function(){
|
274 |
-
var id=0;
|
275 |
-
return function(){
|
276 |
-
return "chart-" + id++;
|
277 |
-
};
|
278 |
-
})(),
|
279 |
-
warn = helpers.warn = function(str){
|
280 |
-
//Method for warning of errors
|
281 |
-
if (window.console && typeof window.console.warn == "function") console.warn(str);
|
282 |
-
},
|
283 |
-
amd = helpers.amd = (typeof define == 'function' && define.amd),
|
284 |
-
//-- Math methods
|
285 |
-
isNumber = helpers.isNumber = function(n){
|
286 |
-
return !isNaN(parseFloat(n)) && isFinite(n);
|
287 |
-
},
|
288 |
-
max = helpers.max = function(array){
|
289 |
-
return Math.max.apply( Math, array );
|
290 |
-
},
|
291 |
-
min = helpers.min = function(array){
|
292 |
-
return Math.min.apply( Math, array );
|
293 |
-
},
|
294 |
-
cap = helpers.cap = function(valueToCap,maxValue,minValue){
|
295 |
-
if(isNumber(maxValue)) {
|
296 |
-
if( valueToCap > maxValue ) {
|
297 |
-
return maxValue;
|
298 |
-
}
|
299 |
-
}
|
300 |
-
else if(isNumber(minValue)){
|
301 |
-
if ( valueToCap < minValue ){
|
302 |
-
return minValue;
|
303 |
-
}
|
304 |
-
}
|
305 |
-
return valueToCap;
|
306 |
-
},
|
307 |
-
getDecimalPlaces = helpers.getDecimalPlaces = function(num){
|
308 |
-
if (num%1!==0 && isNumber(num)){
|
309 |
-
return num.toString().split(".")[1].length;
|
310 |
-
}
|
311 |
-
else {
|
312 |
-
return 0;
|
313 |
-
}
|
314 |
-
},
|
315 |
-
toRadians = helpers.radians = function(degrees){
|
316 |
-
return degrees * (Math.PI/180);
|
317 |
-
},
|
318 |
-
// Gets the angle from vertical upright to the point about a centre.
|
319 |
-
getAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){
|
320 |
-
var distanceFromXCenter = anglePoint.x - centrePoint.x,
|
321 |
-
distanceFromYCenter = anglePoint.y - centrePoint.y,
|
322 |
-
radialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
|
323 |
-
|
324 |
-
|
325 |
-
var angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);
|
326 |
-
|
327 |
-
//If the segment is in the top left quadrant, we need to add another rotation to the angle
|
328 |
-
if (distanceFromXCenter < 0 && distanceFromYCenter < 0){
|
329 |
-
angle += Math.PI*2;
|
330 |
-
}
|
331 |
-
|
332 |
-
return {
|
333 |
-
angle: angle,
|
334 |
-
distance: radialDistanceFromCenter
|
335 |
-
};
|
336 |
-
},
|
337 |
-
aliasPixel = helpers.aliasPixel = function(pixelWidth){
|
338 |
-
return (pixelWidth % 2 === 0) ? 0 : 0.5;
|
339 |
-
},
|
340 |
-
splineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){
|
341 |
-
//Props to Rob Spencer at scaled innovation for his post on splining between points
|
342 |
-
//http://scaledinnovation.com/analytics/splines/aboutSplines.html
|
343 |
-
var d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),
|
344 |
-
d12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),
|
345 |
-
fa=t*d01/(d01+d12),// scaling factor for triangle Ta
|
346 |
-
fb=t*d12/(d01+d12);
|
347 |
-
return {
|
348 |
-
inner : {
|
349 |
-
x : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),
|
350 |
-
y : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)
|
351 |
-
},
|
352 |
-
outer : {
|
353 |
-
x: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),
|
354 |
-
y : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)
|
355 |
-
}
|
356 |
-
};
|
357 |
-
},
|
358 |
-
calculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){
|
359 |
-
return Math.floor(Math.log(val) / Math.LN10);
|
360 |
-
},
|
361 |
-
calculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){
|
362 |
-
|
363 |
-
//Set a minimum step of two - a point at the top of the graph, and a point at the base
|
364 |
-
var minSteps = 2,
|
365 |
-
maxSteps = Math.floor(drawingSize/(textSize * 1.5)),
|
366 |
-
skipFitting = (minSteps >= maxSteps);
|
367 |
-
|
368 |
-
var maxValue = max(valuesArray),
|
369 |
-
minValue = min(valuesArray);
|
370 |
-
|
371 |
-
// We need some degree of seperation here to calculate the scales if all the values are the same
|
372 |
-
// Adding/minusing 0.5 will give us a range of 1.
|
373 |
-
if (maxValue === minValue){
|
374 |
-
maxValue += 0.5;
|
375 |
-
// So we don't end up with a graph with a negative start value if we've said always start from zero
|
376 |
-
if (minValue >= 0.5 && !startFromZero){
|
377 |
-
minValue -= 0.5;
|
378 |
-
}
|
379 |
-
else{
|
380 |
-
// Make up a whole number above the values
|
381 |
-
maxValue += 0.5;
|
382 |
-
}
|
383 |
-
}
|
384 |
-
|
385 |
-
var valueRange = Math.abs(maxValue - minValue),
|
386 |
-
rangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),
|
387 |
-
graphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
|
388 |
-
graphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
|
389 |
-
graphRange = graphMax - graphMin,
|
390 |
-
stepValue = Math.pow(10, rangeOrderOfMagnitude),
|
391 |
-
numberOfSteps = Math.round(graphRange / stepValue);
|
392 |
-
|
393 |
-
//If we have more space on the graph we'll use it to give more definition to the data
|
394 |
-
while((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {
|
395 |
-
if(numberOfSteps > maxSteps){
|
396 |
-
stepValue *=2;
|
397 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
398 |
-
// Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.
|
399 |
-
if (numberOfSteps % 1 !== 0){
|
400 |
-
skipFitting = true;
|
401 |
-
}
|
402 |
-
}
|
403 |
-
//We can fit in double the amount of scale points on the scale
|
404 |
-
else{
|
405 |
-
//If user has declared ints only, and the step value isn't a decimal
|
406 |
-
if (integersOnly && rangeOrderOfMagnitude >= 0){
|
407 |
-
//If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float
|
408 |
-
if(stepValue/2 % 1 === 0){
|
409 |
-
stepValue /=2;
|
410 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
411 |
-
}
|
412 |
-
//If it would make it a float break out of the loop
|
413 |
-
else{
|
414 |
-
break;
|
415 |
-
}
|
416 |
-
}
|
417 |
-
//If the scale doesn't have to be an int, make the scale more granular anyway.
|
418 |
-
else{
|
419 |
-
stepValue /=2;
|
420 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
421 |
-
}
|
422 |
-
|
423 |
-
}
|
424 |
-
}
|
425 |
-
|
426 |
-
if (skipFitting){
|
427 |
-
numberOfSteps = minSteps;
|
428 |
-
stepValue = graphRange / numberOfSteps;
|
429 |
-
}
|
430 |
-
|
431 |
-
return {
|
432 |
-
steps : numberOfSteps,
|
433 |
-
stepValue : stepValue,
|
434 |
-
min : graphMin,
|
435 |
-
max : graphMin + (numberOfSteps * stepValue)
|
436 |
-
};
|
437 |
-
|
438 |
-
},
|
439 |
-
/* jshint ignore:start */
|
440 |
-
// Blows up jshint errors based on the new Function constructor
|
441 |
-
//Templating methods
|
442 |
-
//Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/
|
443 |
-
template = helpers.template = function(templateString, valuesObject){
|
444 |
-
// If templateString is function rather than string-template - call the function for valuesObject
|
445 |
-
if(templateString instanceof Function){
|
446 |
-
return templateString(valuesObject);
|
447 |
-
}
|
448 |
-
|
449 |
-
var cache = {};
|
450 |
-
function tmpl(str, data){
|
451 |
-
// Figure out if we're getting a template, or if we need to
|
452 |
-
// load the template - and be sure to cache the result.
|
453 |
-
var fn = !/\W/.test(str) ?
|
454 |
-
cache[str] = cache[str] :
|
455 |
-
|
456 |
-
// Generate a reusable function that will serve as a template
|
457 |
-
// generator (and which will be cached).
|
458 |
-
new Function("obj",
|
459 |
-
"var p=[],print=function(){p.push.apply(p,arguments);};" +
|
460 |
-
|
461 |
-
// Introduce the data as local variables using with(){}
|
462 |
-
"with(obj){p.push('" +
|
463 |
-
|
464 |
-
// Convert the template into pure JavaScript
|
465 |
-
str
|
466 |
-
.replace(/[\r\t\n]/g, " ")
|
467 |
-
.split("<%").join("\t")
|
468 |
-
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
|
469 |
-
.replace(/\t=(.*?)%>/g, "',$1,'")
|
470 |
-
.split("\t").join("');")
|
471 |
-
.split("%>").join("p.push('")
|
472 |
-
.split("\r").join("\\'") +
|
473 |
-
"');}return p.join('');"
|
474 |
-
);
|
475 |
-
|
476 |
-
// Provide some basic currying to the user
|
477 |
-
return data ? fn( data ) : fn;
|
478 |
-
}
|
479 |
-
return tmpl(templateString,valuesObject);
|
480 |
-
},
|
481 |
-
/* jshint ignore:end */
|
482 |
-
generateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){
|
483 |
-
var labelsArray = new Array(numberOfSteps);
|
484 |
-
if (labelTemplateString){
|
485 |
-
each(labelsArray,function(val,index){
|
486 |
-
labelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});
|
487 |
-
});
|
488 |
-
}
|
489 |
-
return labelsArray;
|
490 |
-
},
|
491 |
-
//--Animation methods
|
492 |
-
//Easing functions adapted from Robert Penner's easing equations
|
493 |
-
//http://www.robertpenner.com/easing/
|
494 |
-
easingEffects = helpers.easingEffects = {
|
495 |
-
linear: function (t) {
|
496 |
-
return t;
|
497 |
-
},
|
498 |
-
easeInQuad: function (t) {
|
499 |
-
return t * t;
|
500 |
-
},
|
501 |
-
easeOutQuad: function (t) {
|
502 |
-
return -1 * t * (t - 2);
|
503 |
-
},
|
504 |
-
easeInOutQuad: function (t) {
|
505 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * t * t;
|
506 |
-
return -1 / 2 * ((--t) * (t - 2) - 1);
|
507 |
-
},
|
508 |
-
easeInCubic: function (t) {
|
509 |
-
return t * t * t;
|
510 |
-
},
|
511 |
-
easeOutCubic: function (t) {
|
512 |
-
return 1 * ((t = t / 1 - 1) * t * t + 1);
|
513 |
-
},
|
514 |
-
easeInOutCubic: function (t) {
|
515 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t;
|
516 |
-
return 1 / 2 * ((t -= 2) * t * t + 2);
|
517 |
-
},
|
518 |
-
easeInQuart: function (t) {
|
519 |
-
return t * t * t * t;
|
520 |
-
},
|
521 |
-
easeOutQuart: function (t) {
|
522 |
-
return -1 * ((t = t / 1 - 1) * t * t * t - 1);
|
523 |
-
},
|
524 |
-
easeInOutQuart: function (t) {
|
525 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t;
|
526 |
-
return -1 / 2 * ((t -= 2) * t * t * t - 2);
|
527 |
-
},
|
528 |
-
easeInQuint: function (t) {
|
529 |
-
return 1 * (t /= 1) * t * t * t * t;
|
530 |
-
},
|
531 |
-
easeOutQuint: function (t) {
|
532 |
-
return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);
|
533 |
-
},
|
534 |
-
easeInOutQuint: function (t) {
|
535 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t * t;
|
536 |
-
return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
|
537 |
-
},
|
538 |
-
easeInSine: function (t) {
|
539 |
-
return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
|
540 |
-
},
|
541 |
-
easeOutSine: function (t) {
|
542 |
-
return 1 * Math.sin(t / 1 * (Math.PI / 2));
|
543 |
-
},
|
544 |
-
easeInOutSine: function (t) {
|
545 |
-
return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
|
546 |
-
},
|
547 |
-
easeInExpo: function (t) {
|
548 |
-
return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
|
549 |
-
},
|
550 |
-
easeOutExpo: function (t) {
|
551 |
-
return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
|
552 |
-
},
|
553 |
-
easeInOutExpo: function (t) {
|
554 |
-
if (t === 0) return 0;
|
555 |
-
if (t === 1) return 1;
|
556 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * Math.pow(2, 10 * (t - 1));
|
557 |
-
return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
|
558 |
-
},
|
559 |
-
easeInCirc: function (t) {
|
560 |
-
if (t >= 1) return t;
|
561 |
-
return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
|
562 |
-
},
|
563 |
-
easeOutCirc: function (t) {
|
564 |
-
return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
|
565 |
-
},
|
566 |
-
easeInOutCirc: function (t) {
|
567 |
-
if ((t /= 1 / 2) < 1) return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
|
568 |
-
return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
|
569 |
-
},
|
570 |
-
easeInElastic: function (t) {
|
571 |
-
var s = 1.70158;
|
572 |
-
var p = 0;
|
573 |
-
var a = 1;
|
574 |
-
if (t === 0) return 0;
|
575 |
-
if ((t /= 1) == 1) return 1;
|
576 |
-
if (!p) p = 1 * 0.3;
|
577 |
-
if (a < Math.abs(1)) {
|
578 |
-
a = 1;
|
579 |
-
s = p / 4;
|
580 |
-
} else s = p / (2 * Math.PI) * Math.asin(1 / a);
|
581 |
-
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
582 |
-
},
|
583 |
-
easeOutElastic: function (t) {
|
584 |
-
var s = 1.70158;
|
585 |
-
var p = 0;
|
586 |
-
var a = 1;
|
587 |
-
if (t === 0) return 0;
|
588 |
-
if ((t /= 1) == 1) return 1;
|
589 |
-
if (!p) p = 1 * 0.3;
|
590 |
-
if (a < Math.abs(1)) {
|
591 |
-
a = 1;
|
592 |
-
s = p / 4;
|
593 |
-
} else s = p / (2 * Math.PI) * Math.asin(1 / a);
|
594 |
-
return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
|
595 |
-
},
|
596 |
-
easeInOutElastic: function (t) {
|
597 |
-
var s = 1.70158;
|
598 |
-
var p = 0;
|
599 |
-
var a = 1;
|
600 |
-
if (t === 0) return 0;
|
601 |
-
if ((t /= 1 / 2) == 2) return 1;
|
602 |
-
if (!p) p = 1 * (0.3 * 1.5);
|
603 |
-
if (a < Math.abs(1)) {
|
604 |
-
a = 1;
|
605 |
-
s = p / 4;
|
606 |
-
} else s = p / (2 * Math.PI) * Math.asin(1 / a);
|
607 |
-
if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
608 |
-
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
|
609 |
-
},
|
610 |
-
easeInBack: function (t) {
|
611 |
-
var s = 1.70158;
|
612 |
-
return 1 * (t /= 1) * t * ((s + 1) * t - s);
|
613 |
-
},
|
614 |
-
easeOutBack: function (t) {
|
615 |
-
var s = 1.70158;
|
616 |
-
return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
|
617 |
-
},
|
618 |
-
easeInOutBack: function (t) {
|
619 |
-
var s = 1.70158;
|
620 |
-
if ((t /= 1 / 2) < 1) return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
|
621 |
-
return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
|
622 |
-
},
|
623 |
-
easeInBounce: function (t) {
|
624 |
-
return 1 - easingEffects.easeOutBounce(1 - t);
|
625 |
-
},
|
626 |
-
easeOutBounce: function (t) {
|
627 |
-
if ((t /= 1) < (1 / 2.75)) {
|
628 |
-
return 1 * (7.5625 * t * t);
|
629 |
-
} else if (t < (2 / 2.75)) {
|
630 |
-
return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
|
631 |
-
} else if (t < (2.5 / 2.75)) {
|
632 |
-
return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
|
633 |
-
} else {
|
634 |
-
return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
|
635 |
-
}
|
636 |
-
},
|
637 |
-
easeInOutBounce: function (t) {
|
638 |
-
if (t < 1 / 2) return easingEffects.easeInBounce(t * 2) * 0.5;
|
639 |
-
return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
|
640 |
-
}
|
641 |
-
},
|
642 |
-
//Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
|
643 |
-
requestAnimFrame = helpers.requestAnimFrame = (function(){
|
644 |
-
return window.requestAnimationFrame ||
|
645 |
-
window.webkitRequestAnimationFrame ||
|
646 |
-
window.mozRequestAnimationFrame ||
|
647 |
-
window.oRequestAnimationFrame ||
|
648 |
-
window.msRequestAnimationFrame ||
|
649 |
-
function(callback) {
|
650 |
-
return window.setTimeout(callback, 1000 / 60);
|
651 |
-
};
|
652 |
-
})(),
|
653 |
-
cancelAnimFrame = helpers.cancelAnimFrame = (function(){
|
654 |
-
return window.cancelAnimationFrame ||
|
655 |
-
window.webkitCancelAnimationFrame ||
|
656 |
-
window.mozCancelAnimationFrame ||
|
657 |
-
window.oCancelAnimationFrame ||
|
658 |
-
window.msCancelAnimationFrame ||
|
659 |
-
function(callback) {
|
660 |
-
return window.clearTimeout(callback, 1000 / 60);
|
661 |
-
};
|
662 |
-
})(),
|
663 |
-
animationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){
|
664 |
-
|
665 |
-
var currentStep = 0,
|
666 |
-
easingFunction = easingEffects[easingString] || easingEffects.linear;
|
667 |
-
|
668 |
-
var animationFrame = function(){
|
669 |
-
currentStep++;
|
670 |
-
var stepDecimal = currentStep/totalSteps;
|
671 |
-
var easeDecimal = easingFunction(stepDecimal);
|
672 |
-
|
673 |
-
callback.call(chartInstance,easeDecimal,stepDecimal, currentStep);
|
674 |
-
onProgress.call(chartInstance,easeDecimal,stepDecimal);
|
675 |
-
if (currentStep < totalSteps){
|
676 |
-
chartInstance.animationFrame = requestAnimFrame(animationFrame);
|
677 |
-
} else{
|
678 |
-
onComplete.apply(chartInstance);
|
679 |
-
}
|
680 |
-
};
|
681 |
-
requestAnimFrame(animationFrame);
|
682 |
-
},
|
683 |
-
//-- DOM methods
|
684 |
-
getRelativePosition = helpers.getRelativePosition = function(evt){
|
685 |
-
var mouseX, mouseY;
|
686 |
-
var e = evt.originalEvent || evt,
|
687 |
-
canvas = evt.currentTarget || evt.srcElement,
|
688 |
-
boundingRect = canvas.getBoundingClientRect();
|
689 |
-
|
690 |
-
if (e.touches){
|
691 |
-
mouseX = e.touches[0].clientX - boundingRect.left;
|
692 |
-
mouseY = e.touches[0].clientY - boundingRect.top;
|
693 |
-
|
694 |
-
}
|
695 |
-
else{
|
696 |
-
mouseX = e.clientX - boundingRect.left;
|
697 |
-
mouseY = e.clientY - boundingRect.top;
|
698 |
-
}
|
699 |
-
|
700 |
-
return {
|
701 |
-
x : mouseX,
|
702 |
-
y : mouseY
|
703 |
-
};
|
704 |
-
|
705 |
-
},
|
706 |
-
addEvent = helpers.addEvent = function(node,eventType,method){
|
707 |
-
if (node.addEventListener){
|
708 |
-
node.addEventListener(eventType,method);
|
709 |
-
} else if (node.attachEvent){
|
710 |
-
node.attachEvent("on"+eventType, method);
|
711 |
-
} else {
|
712 |
-
node["on"+eventType] = method;
|
713 |
-
}
|
714 |
-
},
|
715 |
-
removeEvent = helpers.removeEvent = function(node, eventType, handler){
|
716 |
-
if (node.removeEventListener){
|
717 |
-
node.removeEventListener(eventType, handler, false);
|
718 |
-
} else if (node.detachEvent){
|
719 |
-
node.detachEvent("on"+eventType,handler);
|
720 |
-
} else{
|
721 |
-
node["on" + eventType] = noop;
|
722 |
-
}
|
723 |
-
},
|
724 |
-
bindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){
|
725 |
-
// Create the events object if it's not already present
|
726 |
-
if (!chartInstance.events) chartInstance.events = {};
|
727 |
-
|
728 |
-
each(arrayOfEvents,function(eventName){
|
729 |
-
chartInstance.events[eventName] = function(){
|
730 |
-
handler.apply(chartInstance, arguments);
|
731 |
-
};
|
732 |
-
addEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);
|
733 |
-
});
|
734 |
-
},
|
735 |
-
unbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) {
|
736 |
-
each(arrayOfEvents, function(handler,eventName){
|
737 |
-
removeEvent(chartInstance.chart.canvas, eventName, handler);
|
738 |
-
});
|
739 |
-
},
|
740 |
-
getMaximumWidth = helpers.getMaximumWidth = function(domNode){
|
741 |
-
var container = domNode.parentNode;
|
742 |
-
// TODO = check cross browser stuff with this.
|
743 |
-
return container.clientWidth;
|
744 |
-
},
|
745 |
-
getMaximumHeight = helpers.getMaximumHeight = function(domNode){
|
746 |
-
var container = domNode.parentNode;
|
747 |
-
// TODO = check cross browser stuff with this.
|
748 |
-
return container.clientHeight;
|
749 |
-
},
|
750 |
-
getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support
|
751 |
-
retinaScale = helpers.retinaScale = function(chart){
|
752 |
-
var ctx = chart.ctx,
|
753 |
-
width = chart.canvas.width,
|
754 |
-
height = chart.canvas.height;
|
755 |
-
|
756 |
-
if (window.devicePixelRatio) {
|
757 |
-
ctx.canvas.style.width = width + "px";
|
758 |
-
ctx.canvas.style.height = height + "px";
|
759 |
-
ctx.canvas.height = height * window.devicePixelRatio;
|
760 |
-
ctx.canvas.width = width * window.devicePixelRatio;
|
761 |
-
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
|
762 |
-
}
|
763 |
-
},
|
764 |
-
//-- Canvas methods
|
765 |
-
clear = helpers.clear = function(chart){
|
766 |
-
chart.ctx.clearRect(0,0,chart.width,chart.height);
|
767 |
-
},
|
768 |
-
fontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){
|
769 |
-
return fontStyle + " " + pixelSize+"px " + fontFamily;
|
770 |
-
},
|
771 |
-
longestText = helpers.longestText = function(ctx,font,arrayOfStrings){
|
772 |
-
ctx.font = font;
|
773 |
-
var longest = 0;
|
774 |
-
each(arrayOfStrings,function(string){
|
775 |
-
var textWidth = ctx.measureText(string).width;
|
776 |
-
longest = (textWidth > longest) ? textWidth : longest;
|
777 |
-
});
|
778 |
-
return longest;
|
779 |
-
},
|
780 |
-
drawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){
|
781 |
-
ctx.beginPath();
|
782 |
-
ctx.moveTo(x + radius, y);
|
783 |
-
ctx.lineTo(x + width - radius, y);
|
784 |
-
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
785 |
-
ctx.lineTo(x + width, y + height - radius);
|
786 |
-
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
|
787 |
-
ctx.lineTo(x + radius, y + height);
|
788 |
-
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
789 |
-
ctx.lineTo(x, y + radius);
|
790 |
-
ctx.quadraticCurveTo(x, y, x + radius, y);
|
791 |
-
ctx.closePath();
|
792 |
-
};
|
793 |
-
|
794 |
-
|
795 |
-
//Store a reference to each instance - allowing us to globally resize chart instances on window resize.
|
796 |
-
//Destroy method on the chart will remove the instance of the chart from this reference.
|
797 |
-
Chart.instances = {};
|
798 |
-
|
799 |
-
Chart.Type = function(data,options,chart){
|
800 |
-
this.options = options;
|
801 |
-
this.chart = chart;
|
802 |
-
this.id = uid();
|
803 |
-
//Add the chart instance to the global namespace
|
804 |
-
Chart.instances[this.id] = this;
|
805 |
-
|
806 |
-
// Initialize is always called when a chart type is created
|
807 |
-
// By default it is a no op, but it should be extended
|
808 |
-
if (options.responsive){
|
809 |
-
this.resize();
|
810 |
-
}
|
811 |
-
this.initialize.call(this,data);
|
812 |
-
};
|
813 |
-
|
814 |
-
//Core methods that'll be a part of every chart type
|
815 |
-
extend(Chart.Type.prototype,{
|
816 |
-
initialize : function(){return this;},
|
817 |
-
clear : function(){
|
818 |
-
clear(this.chart);
|
819 |
-
return this;
|
820 |
-
},
|
821 |
-
stop : function(){
|
822 |
-
// Stops any current animation loop occuring
|
823 |
-
helpers.cancelAnimFrame.call(root, this.animationFrame);
|
824 |
-
return this;
|
825 |
-
},
|
826 |
-
resize : function(callback){
|
827 |
-
this.stop();
|
828 |
-
var canvas = this.chart.canvas,
|
829 |
-
newWidth = getMaximumWidth(this.chart.canvas),
|
830 |
-
newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);
|
831 |
-
|
832 |
-
canvas.width = this.chart.width = newWidth;
|
833 |
-
canvas.height = this.chart.height = newHeight;
|
834 |
-
|
835 |
-
retinaScale(this.chart);
|
836 |
-
|
837 |
-
if (typeof callback === "function"){
|
838 |
-
callback.apply(this, Array.prototype.slice.call(arguments, 1));
|
839 |
-
}
|
840 |
-
return this;
|
841 |
-
},
|
842 |
-
reflow : noop,
|
843 |
-
render : function(reflow){
|
844 |
-
if (reflow){
|
845 |
-
this.reflow();
|
846 |
-
}
|
847 |
-
if (this.options.animation && !reflow){
|
848 |
-
helpers.animationLoop(
|
849 |
-
this.draw,
|
850 |
-
this.options.animationSteps,
|
851 |
-
this.options.animationEasing,
|
852 |
-
this.options.onAnimationProgress,
|
853 |
-
this.options.onAnimationComplete,
|
854 |
-
this
|
855 |
-
);
|
856 |
-
}
|
857 |
-
else{
|
858 |
-
this.draw();
|
859 |
-
this.options.onAnimationComplete.call(this);
|
860 |
-
}
|
861 |
-
return this;
|
862 |
-
},
|
863 |
-
generateLegend : function(){
|
864 |
-
return template(this.options.legendTemplate,this);
|
865 |
-
},
|
866 |
-
destroy : function(){
|
867 |
-
this.clear();
|
868 |
-
unbindEvents(this, this.events);
|
869 |
-
delete Chart.instances[this.id];
|
870 |
-
},
|
871 |
-
showTooltip : function(ChartElements, forceRedraw){
|
872 |
-
// Only redraw the chart if we've actually changed what we're hovering on.
|
873 |
-
if (typeof this.activeElements === 'undefined') this.activeElements = [];
|
874 |
-
|
875 |
-
var isChanged = (function(Elements){
|
876 |
-
var changed = false;
|
877 |
-
|
878 |
-
if (Elements.length !== this.activeElements.length){
|
879 |
-
changed = true;
|
880 |
-
return changed;
|
881 |
-
}
|
882 |
-
|
883 |
-
each(Elements, function(element, index){
|
884 |
-
if (element !== this.activeElements[index]){
|
885 |
-
changed = true;
|
886 |
-
}
|
887 |
-
}, this);
|
888 |
-
return changed;
|
889 |
-
}).call(this, ChartElements);
|
890 |
-
|
891 |
-
if (!isChanged && !forceRedraw){
|
892 |
-
return;
|
893 |
-
}
|
894 |
-
else{
|
895 |
-
this.activeElements = ChartElements;
|
896 |
-
}
|
897 |
-
this.draw();
|
898 |
-
if (ChartElements.length > 0){
|
899 |
-
// If we have multiple datasets, show a MultiTooltip for all of the data points at that index
|
900 |
-
if (this.datasets && this.datasets.length > 1) {
|
901 |
-
var dataArray,
|
902 |
-
dataIndex;
|
903 |
-
|
904 |
-
for (var i = this.datasets.length - 1; i >= 0; i--) {
|
905 |
-
dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
|
906 |
-
dataIndex = indexOf(dataArray, ChartElements[0]);
|
907 |
-
if (dataIndex !== -1){
|
908 |
-
break;
|
909 |
-
}
|
910 |
-
}
|
911 |
-
var tooltipLabels = [],
|
912 |
-
tooltipColors = [],
|
913 |
-
medianPosition = (function(index) {
|
914 |
-
|
915 |
-
// Get all the points at that particular index
|
916 |
-
var Elements = [],
|
917 |
-
dataCollection,
|
918 |
-
xPositions = [],
|
919 |
-
yPositions = [],
|
920 |
-
xMax,
|
921 |
-
yMax,
|
922 |
-
xMin,
|
923 |
-
yMin;
|
924 |
-
helpers.each(this.datasets, function(dataset){
|
925 |
-
dataCollection = dataset.points || dataset.bars || dataset.segments;
|
926 |
-
if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){
|
927 |
-
Elements.push(dataCollection[dataIndex]);
|
928 |
-
}
|
929 |
-
});
|
930 |
-
|
931 |
-
helpers.each(Elements, function(element) {
|
932 |
-
xPositions.push(element.x);
|
933 |
-
yPositions.push(element.y);
|
934 |
-
|
935 |
-
|
936 |
-
//Include any colour information about the element
|
937 |
-
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
|
938 |
-
tooltipColors.push({
|
939 |
-
fill: element._saved.fillColor || element.fillColor,
|
940 |
-
stroke: element._saved.strokeColor || element.strokeColor
|
941 |
-
});
|
942 |
-
|
943 |
-
}, this);
|
944 |
-
|
945 |
-
yMin = min(yPositions);
|
946 |
-
yMax = max(yPositions);
|
947 |
-
|
948 |
-
xMin = min(xPositions);
|
949 |
-
xMax = max(xPositions);
|
950 |
-
|
951 |
-
return {
|
952 |
-
x: (xMin > this.chart.width/2) ? xMin : xMax,
|
953 |
-
y: (yMin + yMax)/2
|
954 |
-
};
|
955 |
-
}).call(this, dataIndex);
|
956 |
-
|
957 |
-
new Chart.MultiTooltip({
|
958 |
-
x: medianPosition.x,
|
959 |
-
y: medianPosition.y,
|
960 |
-
xPadding: this.options.tooltipXPadding,
|
961 |
-
yPadding: this.options.tooltipYPadding,
|
962 |
-
xOffset: this.options.tooltipXOffset,
|
963 |
-
fillColor: this.options.tooltipFillColor,
|
964 |
-
textColor: this.options.tooltipFontColor,
|
965 |
-
fontFamily: this.options.tooltipFontFamily,
|
966 |
-
fontStyle: this.options.tooltipFontStyle,
|
967 |
-
fontSize: this.options.tooltipFontSize,
|
968 |
-
titleTextColor: this.options.tooltipTitleFontColor,
|
969 |
-
titleFontFamily: this.options.tooltipTitleFontFamily,
|
970 |
-
titleFontStyle: this.options.tooltipTitleFontStyle,
|
971 |
-
titleFontSize: this.options.tooltipTitleFontSize,
|
972 |
-
cornerRadius: this.options.tooltipCornerRadius,
|
973 |
-
labels: tooltipLabels,
|
974 |
-
legendColors: tooltipColors,
|
975 |
-
legendColorBackground : this.options.multiTooltipKeyBackground,
|
976 |
-
title: ChartElements[0].label,
|
977 |
-
chart: this.chart,
|
978 |
-
ctx: this.chart.ctx
|
979 |
-
}).draw();
|
980 |
-
|
981 |
-
} else {
|
982 |
-
each(ChartElements, function(Element) {
|
983 |
-
var tooltipPosition = Element.tooltipPosition();
|
984 |
-
new Chart.Tooltip({
|
985 |
-
x: Math.round(tooltipPosition.x),
|
986 |
-
y: Math.round(tooltipPosition.y),
|
987 |
-
xPadding: this.options.tooltipXPadding,
|
988 |
-
yPadding: this.options.tooltipYPadding,
|
989 |
-
fillColor: this.options.tooltipFillColor,
|
990 |
-
textColor: this.options.tooltipFontColor,
|
991 |
-
fontFamily: this.options.tooltipFontFamily,
|
992 |
-
fontStyle: this.options.tooltipFontStyle,
|
993 |
-
fontSize: this.options.tooltipFontSize,
|
994 |
-
caretHeight: this.options.tooltipCaretSize,
|
995 |
-
cornerRadius: this.options.tooltipCornerRadius,
|
996 |
-
text: template(this.options.tooltipTemplate, Element),
|
997 |
-
chart: this.chart
|
998 |
-
}).draw();
|
999 |
-
}, this);
|
1000 |
-
}
|
1001 |
-
}
|
1002 |
-
return this;
|
1003 |
-
},
|
1004 |
-
toBase64Image : function(){
|
1005 |
-
return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
|
1006 |
-
}
|
1007 |
-
});
|
1008 |
-
|
1009 |
-
Chart.Type.extend = function(extensions){
|
1010 |
-
|
1011 |
-
var parent = this;
|
1012 |
-
|
1013 |
-
var ChartType = function(){
|
1014 |
-
return parent.apply(this,arguments);
|
1015 |
-
};
|
1016 |
-
|
1017 |
-
//Copy the prototype object of the this class
|
1018 |
-
ChartType.prototype = clone(parent.prototype);
|
1019 |
-
//Now overwrite some of the properties in the base class with the new extensions
|
1020 |
-
extend(ChartType.prototype, extensions);
|
1021 |
-
|
1022 |
-
ChartType.extend = Chart.Type.extend;
|
1023 |
-
|
1024 |
-
if (extensions.name || parent.prototype.name){
|
1025 |
-
|
1026 |
-
var chartName = extensions.name || parent.prototype.name;
|
1027 |
-
//Assign any potential default values of the new chart type
|
1028 |
-
|
1029 |
-
//If none are defined, we'll use a clone of the chart type this is being extended from.
|
1030 |
-
//I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart
|
1031 |
-
//doesn't define some defaults of their own.
|
1032 |
-
|
1033 |
-
var baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {};
|
1034 |
-
|
1035 |
-
Chart.defaults[chartName] = extend(baseDefaults,extensions.defaults);
|
1036 |
-
|
1037 |
-
Chart.types[chartName] = ChartType;
|
1038 |
-
|
1039 |
-
//Register this new chart type in the Chart prototype
|
1040 |
-
Chart.prototype[chartName] = function(data,options){
|
1041 |
-
var config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {});
|
1042 |
-
return new ChartType(data,config,this);
|
1043 |
-
};
|
1044 |
-
} else{
|
1045 |
-
warn("Name not provided for this chart, so it hasn't been registered");
|
1046 |
-
}
|
1047 |
-
return parent;
|
1048 |
-
};
|
1049 |
-
|
1050 |
-
Chart.Element = function(configuration){
|
1051 |
-
extend(this,configuration);
|
1052 |
-
this.initialize.apply(this,arguments);
|
1053 |
-
this.save();
|
1054 |
-
};
|
1055 |
-
extend(Chart.Element.prototype,{
|
1056 |
-
initialize : function(){},
|
1057 |
-
restore : function(props){
|
1058 |
-
if (!props){
|
1059 |
-
extend(this,this._saved);
|
1060 |
-
} else {
|
1061 |
-
each(props,function(key){
|
1062 |
-
this[key] = this._saved[key];
|
1063 |
-
},this);
|
1064 |
-
}
|
1065 |
-
return this;
|
1066 |
-
},
|
1067 |
-
save : function(){
|
1068 |
-
this._saved = clone(this);
|
1069 |
-
delete this._saved._saved;
|
1070 |
-
return this;
|
1071 |
-
},
|
1072 |
-
update : function(newProps){
|
1073 |
-
each(newProps,function(value,key){
|
1074 |
-
this._saved[key] = this[key];
|
1075 |
-
this[key] = value;
|
1076 |
-
},this);
|
1077 |
-
return this;
|
1078 |
-
},
|
1079 |
-
transition : function(props,ease){
|
1080 |
-
each(props,function(value,key){
|
1081 |
-
this[key] = ((value - this._saved[key]) * ease) + this._saved[key];
|
1082 |
-
},this);
|
1083 |
-
return this;
|
1084 |
-
},
|
1085 |
-
tooltipPosition : function(){
|
1086 |
-
return {
|
1087 |
-
x : this.x,
|
1088 |
-
y : this.y
|
1089 |
-
};
|
1090 |
-
},
|
1091 |
-
hasValue: function(){
|
1092 |
-
return isNumber(this.value);
|
1093 |
-
}
|
1094 |
-
});
|
1095 |
-
|
1096 |
-
Chart.Element.extend = inherits;
|
1097 |
-
|
1098 |
-
|
1099 |
-
Chart.Point = Chart.Element.extend({
|
1100 |
-
display: true,
|
1101 |
-
inRange: function(chartX,chartY){
|
1102 |
-
var hitDetectionRange = this.hitDetectionRadius + this.radius;
|
1103 |
-
return ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2));
|
1104 |
-
},
|
1105 |
-
draw : function(){
|
1106 |
-
if (this.display){
|
1107 |
-
var ctx = this.ctx;
|
1108 |
-
ctx.beginPath();
|
1109 |
-
|
1110 |
-
ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
|
1111 |
-
ctx.closePath();
|
1112 |
-
|
1113 |
-
ctx.strokeStyle = this.strokeColor;
|
1114 |
-
ctx.lineWidth = this.strokeWidth;
|
1115 |
-
|
1116 |
-
ctx.fillStyle = this.fillColor;
|
1117 |
-
|
1118 |
-
ctx.fill();
|
1119 |
-
ctx.stroke();
|
1120 |
-
}
|
1121 |
-
|
1122 |
-
|
1123 |
-
//Quick debug for bezier curve splining
|
1124 |
-
//Highlights control points and the line between them.
|
1125 |
-
//Handy for dev - stripped in the min version.
|
1126 |
-
|
1127 |
-
// ctx.save();
|
1128 |
-
// ctx.fillStyle = "black";
|
1129 |
-
// ctx.strokeStyle = "black"
|
1130 |
-
// ctx.beginPath();
|
1131 |
-
// ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2);
|
1132 |
-
// ctx.fill();
|
1133 |
-
|
1134 |
-
// ctx.beginPath();
|
1135 |
-
// ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2);
|
1136 |
-
// ctx.fill();
|
1137 |
-
|
1138 |
-
// ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);
|
1139 |
-
// ctx.lineTo(this.x, this.y);
|
1140 |
-
// ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);
|
1141 |
-
// ctx.stroke();
|
1142 |
-
|
1143 |
-
// ctx.restore();
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
}
|
1148 |
-
});
|
1149 |
-
|
1150 |
-
Chart.Arc = Chart.Element.extend({
|
1151 |
-
inRange : function(chartX,chartY){
|
1152 |
-
|
1153 |
-
var pointRelativePosition = helpers.getAngleFromPoint(this, {
|
1154 |
-
x: chartX,
|
1155 |
-
y: chartY
|
1156 |
-
});
|
1157 |
-
|
1158 |
-
//Check if within the range of the open/close angle
|
1159 |
-
var betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle),
|
1160 |
-
withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius);
|
1161 |
-
|
1162 |
-
return (betweenAngles && withinRadius);
|
1163 |
-
//Ensure within the outside of the arc centre, but inside arc outer
|
1164 |
-
},
|
1165 |
-
tooltipPosition : function(){
|
1166 |
-
var centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2),
|
1167 |
-
rangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius;
|
1168 |
-
return {
|
1169 |
-
x : this.x + (Math.cos(centreAngle) * rangeFromCentre),
|
1170 |
-
y : this.y + (Math.sin(centreAngle) * rangeFromCentre)
|
1171 |
-
};
|
1172 |
-
},
|
1173 |
-
draw : function(animationPercent){
|
1174 |
-
|
1175 |
-
var easingDecimal = animationPercent || 1;
|
1176 |
-
|
1177 |
-
var ctx = this.ctx;
|
1178 |
-
|
1179 |
-
ctx.beginPath();
|
1180 |
-
|
1181 |
-
ctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle);
|
1182 |
-
|
1183 |
-
ctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true);
|
1184 |
-
|
1185 |
-
ctx.closePath();
|
1186 |
-
ctx.strokeStyle = this.strokeColor;
|
1187 |
-
ctx.lineWidth = this.strokeWidth;
|
1188 |
-
|
1189 |
-
ctx.fillStyle = this.fillColor;
|
1190 |
-
|
1191 |
-
ctx.fill();
|
1192 |
-
ctx.lineJoin = 'bevel';
|
1193 |
-
|
1194 |
-
if (this.showStroke){
|
1195 |
-
ctx.stroke();
|
1196 |
-
}
|
1197 |
-
}
|
1198 |
-
});
|
1199 |
-
|
1200 |
-
Chart.Rectangle = Chart.Element.extend({
|
1201 |
-
draw : function(){
|
1202 |
-
var ctx = this.ctx,
|
1203 |
-
halfWidth = this.width/2,
|
1204 |
-
leftX = this.x - halfWidth,
|
1205 |
-
rightX = this.x + halfWidth,
|
1206 |
-
top = this.base - (this.base - this.y),
|
1207 |
-
halfStroke = this.strokeWidth / 2;
|
1208 |
-
|
1209 |
-
// Canvas doesn't allow us to stroke inside the width so we can
|
1210 |
-
// adjust the sizes to fit if we're setting a stroke on the line
|
1211 |
-
if (this.showStroke){
|
1212 |
-
leftX += halfStroke;
|
1213 |
-
rightX -= halfStroke;
|
1214 |
-
top += halfStroke;
|
1215 |
-
}
|
1216 |
-
|
1217 |
-
ctx.beginPath();
|
1218 |
-
|
1219 |
-
ctx.fillStyle = this.fillColor;
|
1220 |
-
ctx.strokeStyle = this.strokeColor;
|
1221 |
-
ctx.lineWidth = this.strokeWidth;
|
1222 |
-
|
1223 |
-
// It'd be nice to keep this class totally generic to any rectangle
|
1224 |
-
// and simply specify which border to miss out.
|
1225 |
-
ctx.moveTo(leftX, this.base);
|
1226 |
-
ctx.lineTo(leftX, top);
|
1227 |
-
ctx.lineTo(rightX, top);
|
1228 |
-
ctx.lineTo(rightX, this.base);
|
1229 |
-
ctx.fill();
|
1230 |
-
if (this.showStroke){
|
1231 |
-
ctx.stroke();
|
1232 |
-
}
|
1233 |
-
},
|
1234 |
-
height : function(){
|
1235 |
-
return this.base - this.y;
|
1236 |
-
},
|
1237 |
-
inRange : function(chartX,chartY){
|
1238 |
-
return (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);
|
1239 |
-
}
|
1240 |
-
});
|
1241 |
-
|
1242 |
-
Chart.Tooltip = Chart.Element.extend({
|
1243 |
-
draw : function(){
|
1244 |
-
|
1245 |
-
var ctx = this.chart.ctx;
|
1246 |
-
|
1247 |
-
ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
|
1248 |
-
|
1249 |
-
this.xAlign = "center";
|
1250 |
-
this.yAlign = "above";
|
1251 |
-
|
1252 |
-
//Distance between the actual element.y position and the start of the tooltip caret
|
1253 |
-
var caretPadding = 2;
|
1254 |
-
|
1255 |
-
var tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,
|
1256 |
-
tooltipRectHeight = this.fontSize + 2*this.yPadding,
|
1257 |
-
tooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;
|
1258 |
-
|
1259 |
-
if (this.x + tooltipWidth/2 >this.chart.width){
|
1260 |
-
this.xAlign = "left";
|
1261 |
-
} else if (this.x - tooltipWidth/2 < 0){
|
1262 |
-
this.xAlign = "right";
|
1263 |
-
}
|
1264 |
-
|
1265 |
-
if (this.y - tooltipHeight < 0){
|
1266 |
-
this.yAlign = "below";
|
1267 |
-
}
|
1268 |
-
|
1269 |
-
|
1270 |
-
var tooltipX = this.x - tooltipWidth/2,
|
1271 |
-
tooltipY = this.y - tooltipHeight;
|
1272 |
-
|
1273 |
-
ctx.fillStyle = this.fillColor;
|
1274 |
-
|
1275 |
-
switch(this.yAlign)
|
1276 |
-
{
|
1277 |
-
case "above":
|
1278 |
-
//Draw a caret above the x/y
|
1279 |
-
ctx.beginPath();
|
1280 |
-
ctx.moveTo(this.x,this.y - caretPadding);
|
1281 |
-
ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));
|
1282 |
-
ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));
|
1283 |
-
ctx.closePath();
|
1284 |
-
ctx.fill();
|
1285 |
-
break;
|
1286 |
-
case "below":
|
1287 |
-
tooltipY = this.y + caretPadding + this.caretHeight;
|
1288 |
-
//Draw a caret below the x/y
|
1289 |
-
ctx.beginPath();
|
1290 |
-
ctx.moveTo(this.x, this.y + caretPadding);
|
1291 |
-
ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);
|
1292 |
-
ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);
|
1293 |
-
ctx.closePath();
|
1294 |
-
ctx.fill();
|
1295 |
-
break;
|
1296 |
-
}
|
1297 |
-
|
1298 |
-
switch(this.xAlign)
|
1299 |
-
{
|
1300 |
-
case "left":
|
1301 |
-
tooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);
|
1302 |
-
break;
|
1303 |
-
case "right":
|
1304 |
-
tooltipX = this.x - (this.cornerRadius + this.caretHeight);
|
1305 |
-
break;
|
1306 |
-
}
|
1307 |
-
|
1308 |
-
drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);
|
1309 |
-
|
1310 |
-
ctx.fill();
|
1311 |
-
|
1312 |
-
ctx.fillStyle = this.textColor;
|
1313 |
-
ctx.textAlign = "center";
|
1314 |
-
ctx.textBaseline = "middle";
|
1315 |
-
ctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);
|
1316 |
-
}
|
1317 |
-
});
|
1318 |
-
|
1319 |
-
Chart.MultiTooltip = Chart.Element.extend({
|
1320 |
-
initialize : function(){
|
1321 |
-
this.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
|
1322 |
-
|
1323 |
-
this.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily);
|
1324 |
-
|
1325 |
-
this.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5;
|
1326 |
-
|
1327 |
-
this.ctx.font = this.titleFont;
|
1328 |
-
|
1329 |
-
var titleWidth = this.ctx.measureText(this.title).width,
|
1330 |
-
//Label has a legend square as well so account for this.
|
1331 |
-
labelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,
|
1332 |
-
longestTextWidth = max([labelWidth,titleWidth]);
|
1333 |
-
|
1334 |
-
this.width = longestTextWidth + (this.xPadding*2);
|
1335 |
-
|
1336 |
-
|
1337 |
-
var halfHeight = this.height/2;
|
1338 |
-
|
1339 |
-
//Check to ensure the height will fit on the canvas
|
1340 |
-
//The three is to buffer form the very
|
1341 |
-
if (this.y - halfHeight < 0 ){
|
1342 |
-
this.y = halfHeight;
|
1343 |
-
} else if (this.y + halfHeight > this.chart.height){
|
1344 |
-
this.y = this.chart.height - halfHeight;
|
1345 |
-
}
|
1346 |
-
|
1347 |
-
//Decide whether to align left or right based on position on canvas
|
1348 |
-
if (this.x > this.chart.width/2){
|
1349 |
-
this.x -= this.xOffset + this.width;
|
1350 |
-
} else {
|
1351 |
-
this.x += this.xOffset;
|
1352 |
-
}
|
1353 |
-
|
1354 |
-
|
1355 |
-
},
|
1356 |
-
getLineHeight : function(index){
|
1357 |
-
var baseLineHeight = this.y - (this.height/2) + this.yPadding,
|
1358 |
-
afterTitleIndex = index-1;
|
1359 |
-
|
1360 |
-
//If the index is zero, we're getting the title
|
1361 |
-
if (index === 0){
|
1362 |
-
return baseLineHeight + this.titleFontSize/2;
|
1363 |
-
} else{
|
1364 |
-
return baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5;
|
1365 |
-
}
|
1366 |
-
|
1367 |
-
},
|
1368 |
-
draw : function(){
|
1369 |
-
drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);
|
1370 |
-
var ctx = this.ctx;
|
1371 |
-
ctx.fillStyle = this.fillColor;
|
1372 |
-
ctx.fill();
|
1373 |
-
ctx.closePath();
|
1374 |
-
|
1375 |
-
ctx.textAlign = "left";
|
1376 |
-
ctx.textBaseline = "middle";
|
1377 |
-
ctx.fillStyle = this.titleTextColor;
|
1378 |
-
ctx.font = this.titleFont;
|
1379 |
-
|
1380 |
-
ctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));
|
1381 |
-
|
1382 |
-
ctx.font = this.font;
|
1383 |
-
helpers.each(this.labels,function(label,index){
|
1384 |
-
ctx.fillStyle = this.textColor;
|
1385 |
-
ctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));
|
1386 |
-
|
1387 |
-
//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)
|
1388 |
-
//ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1389 |
-
//Instead we'll make a white filled block to put the legendColour palette over.
|
1390 |
-
|
1391 |
-
ctx.fillStyle = this.legendColorBackground;
|
1392 |
-
ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1393 |
-
|
1394 |
-
ctx.fillStyle = this.legendColors[index].fill;
|
1395 |
-
ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1396 |
-
|
1397 |
-
|
1398 |
-
},this);
|
1399 |
-
}
|
1400 |
-
});
|
1401 |
-
|
1402 |
-
Chart.Scale = Chart.Element.extend({
|
1403 |
-
initialize : function(){
|
1404 |
-
this.fit();
|
1405 |
-
},
|
1406 |
-
buildYLabels : function(){
|
1407 |
-
this.yLabels = [];
|
1408 |
-
|
1409 |
-
var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
|
1410 |
-
|
1411 |
-
for (var i=0; i<=this.steps; i++){
|
1412 |
-
this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
|
1413 |
-
}
|
1414 |
-
this.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0;
|
1415 |
-
},
|
1416 |
-
addXLabel : function(label){
|
1417 |
-
this.xLabels.push(label);
|
1418 |
-
this.valuesCount++;
|
1419 |
-
this.fit();
|
1420 |
-
},
|
1421 |
-
removeXLabel : function(){
|
1422 |
-
this.xLabels.shift();
|
1423 |
-
this.valuesCount--;
|
1424 |
-
this.fit();
|
1425 |
-
},
|
1426 |
-
// Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use
|
1427 |
-
fit: function(){
|
1428 |
-
// First we need the width of the yLabels, assuming the xLabels aren't rotated
|
1429 |
-
|
1430 |
-
// To do that we need the base line at the top and base of the chart, assuming there is no x label rotation
|
1431 |
-
this.startPoint = (this.display) ? this.fontSize : 0;
|
1432 |
-
this.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels
|
1433 |
-
|
1434 |
-
// Apply padding settings to the start and end point.
|
1435 |
-
this.startPoint += this.padding;
|
1436 |
-
this.endPoint -= this.padding;
|
1437 |
-
|
1438 |
-
// Cache the starting height, so can determine if we need to recalculate the scale yAxis
|
1439 |
-
var cachedHeight = this.endPoint - this.startPoint,
|
1440 |
-
cachedYLabelWidth;
|
1441 |
-
|
1442 |
-
// Build the current yLabels so we have an idea of what size they'll be to start
|
1443 |
-
/*
|
1444 |
-
* This sets what is returned from calculateScaleRange as static properties of this class:
|
1445 |
-
*
|
1446 |
-
this.steps;
|
1447 |
-
this.stepValue;
|
1448 |
-
this.min;
|
1449 |
-
this.max;
|
1450 |
-
*
|
1451 |
-
*/
|
1452 |
-
this.calculateYRange(cachedHeight);
|
1453 |
-
|
1454 |
-
// With these properties set we can now build the array of yLabels
|
1455 |
-
// and also the width of the largest yLabel
|
1456 |
-
this.buildYLabels();
|
1457 |
-
|
1458 |
-
this.calculateXLabelRotation();
|
1459 |
-
|
1460 |
-
while((cachedHeight > this.endPoint - this.startPoint)){
|
1461 |
-
cachedHeight = this.endPoint - this.startPoint;
|
1462 |
-
cachedYLabelWidth = this.yLabelWidth;
|
1463 |
-
|
1464 |
-
this.calculateYRange(cachedHeight);
|
1465 |
-
this.buildYLabels();
|
1466 |
-
|
1467 |
-
// Only go through the xLabel loop again if the yLabel width has changed
|
1468 |
-
if (cachedYLabelWidth < this.yLabelWidth){
|
1469 |
-
this.calculateXLabelRotation();
|
1470 |
-
}
|
1471 |
-
}
|
1472 |
-
|
1473 |
-
},
|
1474 |
-
calculateXLabelRotation : function(){
|
1475 |
-
//Get the width of each grid by calculating the difference
|
1476 |
-
//between x offsets between 0 and 1.
|
1477 |
-
|
1478 |
-
this.ctx.font = this.font;
|
1479 |
-
|
1480 |
-
var firstWidth = this.ctx.measureText(this.xLabels[0]).width,
|
1481 |
-
lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,
|
1482 |
-
firstRotated,
|
1483 |
-
lastRotated;
|
1484 |
-
|
1485 |
-
|
1486 |
-
this.xScalePaddingRight = lastWidth/2 + 3;
|
1487 |
-
this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10;
|
1488 |
-
|
1489 |
-
this.xLabelRotation = 0;
|
1490 |
-
if (this.display){
|
1491 |
-
var originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),
|
1492 |
-
cosRotation,
|
1493 |
-
firstRotatedWidth;
|
1494 |
-
this.xLabelWidth = originalLabelWidth;
|
1495 |
-
//Allow 3 pixels x2 padding either side for label readability
|
1496 |
-
var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;
|
1497 |
-
|
1498 |
-
//Max label rotate should be 90 - also act as a loop counter
|
1499 |
-
while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){
|
1500 |
-
cosRotation = Math.cos(toRadians(this.xLabelRotation));
|
1501 |
-
|
1502 |
-
firstRotated = cosRotation * firstWidth;
|
1503 |
-
lastRotated = cosRotation * lastWidth;
|
1504 |
-
|
1505 |
-
// We're right aligning the text now.
|
1506 |
-
if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8){
|
1507 |
-
this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
|
1508 |
-
}
|
1509 |
-
this.xScalePaddingRight = this.fontSize/2;
|
1510 |
-
|
1511 |
-
|
1512 |
-
this.xLabelRotation++;
|
1513 |
-
this.xLabelWidth = cosRotation * originalLabelWidth;
|
1514 |
-
|
1515 |
-
}
|
1516 |
-
if (this.xLabelRotation > 0){
|
1517 |
-
this.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;
|
1518 |
-
}
|
1519 |
-
}
|
1520 |
-
else{
|
1521 |
-
this.xLabelWidth = 0;
|
1522 |
-
this.xScalePaddingRight = this.padding;
|
1523 |
-
this.xScalePaddingLeft = this.padding;
|
1524 |
-
}
|
1525 |
-
|
1526 |
-
},
|
1527 |
-
// Needs to be overidden in each Chart type
|
1528 |
-
// Otherwise we need to pass all the data into the scale class
|
1529 |
-
calculateYRange: noop,
|
1530 |
-
drawingArea: function(){
|
1531 |
-
return this.startPoint - this.endPoint;
|
1532 |
-
},
|
1533 |
-
calculateY : function(value){
|
1534 |
-
var scalingFactor = this.drawingArea() / (this.min - this.max);
|
1535 |
-
return this.endPoint - (scalingFactor * (value - this.min));
|
1536 |
-
},
|
1537 |
-
calculateX : function(index){
|
1538 |
-
var isRotated = (this.xLabelRotation > 0),
|
1539 |
-
// innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,
|
1540 |
-
innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
|
1541 |
-
valueWidth = innerWidth/(this.valuesCount - ((this.offsetGridLines) ? 0 : 1)),
|
1542 |
-
valueOffset = (valueWidth * index) + this.xScalePaddingLeft;
|
1543 |
-
|
1544 |
-
if (this.offsetGridLines){
|
1545 |
-
valueOffset += (valueWidth/2);
|
1546 |
-
}
|
1547 |
-
|
1548 |
-
return Math.round(valueOffset);
|
1549 |
-
},
|
1550 |
-
update : function(newProps){
|
1551 |
-
helpers.extend(this, newProps);
|
1552 |
-
this.fit();
|
1553 |
-
},
|
1554 |
-
draw : function(){
|
1555 |
-
var ctx = this.ctx,
|
1556 |
-
yLabelGap = (this.endPoint - this.startPoint) / this.steps,
|
1557 |
-
xStart = Math.round(this.xScalePaddingLeft);
|
1558 |
-
if (this.display){
|
1559 |
-
ctx.fillStyle = this.textColor;
|
1560 |
-
ctx.font = this.font;
|
1561 |
-
each(this.yLabels,function(labelString,index){
|
1562 |
-
var yLabelCenter = this.endPoint - (yLabelGap * index),
|
1563 |
-
linePositionY = Math.round(yLabelCenter);
|
1564 |
-
|
1565 |
-
ctx.textAlign = "right";
|
1566 |
-
ctx.textBaseline = "middle";
|
1567 |
-
if (this.showLabels){
|
1568 |
-
ctx.fillText(labelString,xStart - 10,yLabelCenter);
|
1569 |
-
}
|
1570 |
-
ctx.beginPath();
|
1571 |
-
if (index > 0){
|
1572 |
-
// This is a grid line in the centre, so drop that
|
1573 |
-
ctx.lineWidth = this.gridLineWidth;
|
1574 |
-
ctx.strokeStyle = this.gridLineColor;
|
1575 |
-
} else {
|
1576 |
-
// This is the first line on the scale
|
1577 |
-
ctx.lineWidth = this.lineWidth;
|
1578 |
-
ctx.strokeStyle = this.lineColor;
|
1579 |
-
}
|
1580 |
-
|
1581 |
-
linePositionY += helpers.aliasPixel(ctx.lineWidth);
|
1582 |
-
|
1583 |
-
ctx.moveTo(xStart, linePositionY);
|
1584 |
-
ctx.lineTo(this.width, linePositionY);
|
1585 |
-
ctx.stroke();
|
1586 |
-
ctx.closePath();
|
1587 |
-
|
1588 |
-
ctx.lineWidth = this.lineWidth;
|
1589 |
-
ctx.strokeStyle = this.lineColor;
|
1590 |
-
ctx.beginPath();
|
1591 |
-
ctx.moveTo(xStart - 5, linePositionY);
|
1592 |
-
ctx.lineTo(xStart, linePositionY);
|
1593 |
-
ctx.stroke();
|
1594 |
-
ctx.closePath();
|
1595 |
-
|
1596 |
-
},this);
|
1597 |
-
|
1598 |
-
each(this.xLabels,function(label,index){
|
1599 |
-
var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
|
1600 |
-
// Check to see if line/bar here and decide where to place the line
|
1601 |
-
linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
|
1602 |
-
isRotated = (this.xLabelRotation > 0);
|
1603 |
-
|
1604 |
-
ctx.beginPath();
|
1605 |
-
|
1606 |
-
if (index > 0){
|
1607 |
-
// This is a grid line in the centre, so drop that
|
1608 |
-
ctx.lineWidth = this.gridLineWidth;
|
1609 |
-
ctx.strokeStyle = this.gridLineColor;
|
1610 |
-
} else {
|
1611 |
-
// This is the first line on the scale
|
1612 |
-
ctx.lineWidth = this.lineWidth;
|
1613 |
-
ctx.strokeStyle = this.lineColor;
|
1614 |
-
}
|
1615 |
-
ctx.moveTo(linePos,this.endPoint);
|
1616 |
-
ctx.lineTo(linePos,this.startPoint - 3);
|
1617 |
-
ctx.stroke();
|
1618 |
-
ctx.closePath();
|
1619 |
-
|
1620 |
-
|
1621 |
-
ctx.lineWidth = this.lineWidth;
|
1622 |
-
ctx.strokeStyle = this.lineColor;
|
1623 |
-
|
1624 |
-
|
1625 |
-
// Small lines at the bottom of the base grid line
|
1626 |
-
ctx.beginPath();
|
1627 |
-
ctx.moveTo(linePos,this.endPoint);
|
1628 |
-
ctx.lineTo(linePos,this.endPoint + 5);
|
1629 |
-
ctx.stroke();
|
1630 |
-
ctx.closePath();
|
1631 |
-
|
1632 |
-
ctx.save();
|
1633 |
-
ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);
|
1634 |
-
ctx.rotate(toRadians(this.xLabelRotation)*-1);
|
1635 |
-
ctx.font = this.font;
|
1636 |
-
ctx.textAlign = (isRotated) ? "right" : "center";
|
1637 |
-
ctx.textBaseline = (isRotated) ? "middle" : "top";
|
1638 |
-
ctx.fillText(label, 0, 0);
|
1639 |
-
ctx.restore();
|
1640 |
-
},this);
|
1641 |
-
|
1642 |
-
}
|
1643 |
-
}
|
1644 |
-
|
1645 |
-
});
|
1646 |
-
|
1647 |
-
Chart.RadialScale = Chart.Element.extend({
|
1648 |
-
initialize: function(){
|
1649 |
-
this.size = min([this.height, this.width]);
|
1650 |
-
this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
|
1651 |
-
},
|
1652 |
-
calculateCenterOffset: function(value){
|
1653 |
-
// Take into account half font size + the yPadding of the top value
|
1654 |
-
var scalingFactor = this.drawingArea / (this.max - this.min);
|
1655 |
-
|
1656 |
-
return (value - this.min) * scalingFactor;
|
1657 |
-
},
|
1658 |
-
update : function(){
|
1659 |
-
if (!this.lineArc){
|
1660 |
-
this.setScaleSize();
|
1661 |
-
} else {
|
1662 |
-
this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
|
1663 |
-
}
|
1664 |
-
this.buildYLabels();
|
1665 |
-
},
|
1666 |
-
buildYLabels: function(){
|
1667 |
-
this.yLabels = [];
|
1668 |
-
|
1669 |
-
var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
|
1670 |
-
|
1671 |
-
for (var i=0; i<=this.steps; i++){
|
1672 |
-
this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
|
1673 |
-
}
|
1674 |
-
},
|
1675 |
-
getCircumference : function(){
|
1676 |
-
return ((Math.PI*2) / this.valuesCount);
|
1677 |
-
},
|
1678 |
-
setScaleSize: function(){
|
1679 |
-
/*
|
1680 |
-
* Right, this is really confusing and there is a lot of maths going on here
|
1681 |
-
* The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
|
1682 |
-
*
|
1683 |
-
* Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
|
1684 |
-
*
|
1685 |
-
* Solution:
|
1686 |
-
*
|
1687 |
-
* We assume the radius of the polygon is half the size of the canvas at first
|
1688 |
-
* at each index we check if the text overlaps.
|
1689 |
-
*
|
1690 |
-
* Where it does, we store that angle and that index.
|
1691 |
-
*
|
1692 |
-
* After finding the largest index and angle we calculate how much we need to remove
|
1693 |
-
* from the shape radius to move the point inwards by that x.
|
1694 |
-
*
|
1695 |
-
* We average the left and right distances to get the maximum shape radius that can fit in the box
|
1696 |
-
* along with labels.
|
1697 |
-
*
|
1698 |
-
* Once we have that, we can find the centre point for the chart, by taking the x text protrusion
|
1699 |
-
* on each side, removing that from the size, halving it and adding the left x protrusion width.
|
1700 |
-
*
|
1701 |
-
* This will mean we have a shape fitted to the canvas, as large as it can be with the labels
|
1702 |
-
* and position it in the most space efficient manner
|
1703 |
-
*
|
1704 |
-
* https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
|
1705 |
-
*/
|
1706 |
-
|
1707 |
-
|
1708 |
-
// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
|
1709 |
-
// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
|
1710 |
-
var largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),
|
1711 |
-
pointPosition,
|
1712 |
-
i,
|
1713 |
-
textWidth,
|
1714 |
-
halfTextWidth,
|
1715 |
-
furthestRight = this.width,
|
1716 |
-
furthestRightIndex,
|
1717 |
-
furthestRightAngle,
|
1718 |
-
furthestLeft = 0,
|
1719 |
-
furthestLeftIndex,
|
1720 |
-
furthestLeftAngle,
|
1721 |
-
xProtrusionLeft,
|
1722 |
-
xProtrusionRight,
|
1723 |
-
radiusReductionRight,
|
1724 |
-
radiusReductionLeft,
|
1725 |
-
maxWidthRadius;
|
1726 |
-
this.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
|
1727 |
-
for (i=0;i<this.valuesCount;i++){
|
1728 |
-
// 5px to space the text slightly out - similar to what we do in the draw function.
|
1729 |
-
pointPosition = this.getPointPosition(i, largestPossibleRadius);
|
1730 |
-
textWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;
|
1731 |
-
if (i === 0 || i === this.valuesCount/2){
|
1732 |
-
// If we're at index zero, or exactly the middle, we're at exactly the top/bottom
|
1733 |
-
// of the radar chart, so text will be aligned centrally, so we'll half it and compare
|
1734 |
-
// w/left and right text sizes
|
1735 |
-
halfTextWidth = textWidth/2;
|
1736 |
-
if (pointPosition.x + halfTextWidth > furthestRight) {
|
1737 |
-
furthestRight = pointPosition.x + halfTextWidth;
|
1738 |
-
furthestRightIndex = i;
|
1739 |
-
}
|
1740 |
-
if (pointPosition.x - halfTextWidth < furthestLeft) {
|
1741 |
-
furthestLeft = pointPosition.x - halfTextWidth;
|
1742 |
-
furthestLeftIndex = i;
|
1743 |
-
}
|
1744 |
-
}
|
1745 |
-
else if (i < this.valuesCount/2) {
|
1746 |
-
// Less than half the values means we'll left align the text
|
1747 |
-
if (pointPosition.x + textWidth > furthestRight) {
|
1748 |
-
furthestRight = pointPosition.x + textWidth;
|
1749 |
-
furthestRightIndex = i;
|
1750 |
-
}
|
1751 |
-
}
|
1752 |
-
else if (i > this.valuesCount/2){
|
1753 |
-
// More than half the values means we'll right align the text
|
1754 |
-
if (pointPosition.x - textWidth < furthestLeft) {
|
1755 |
-
furthestLeft = pointPosition.x - textWidth;
|
1756 |
-
furthestLeftIndex = i;
|
1757 |
-
}
|
1758 |
-
}
|
1759 |
-
}
|
1760 |
-
|
1761 |
-
xProtrusionLeft = furthestLeft;
|
1762 |
-
|
1763 |
-
xProtrusionRight = Math.ceil(furthestRight - this.width);
|
1764 |
-
|
1765 |
-
furthestRightAngle = this.getIndexAngle(furthestRightIndex);
|
1766 |
-
|
1767 |
-
furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);
|
1768 |
-
|
1769 |
-
radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);
|
1770 |
-
|
1771 |
-
radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);
|
1772 |
-
|
1773 |
-
// Ensure we actually need to reduce the size of the chart
|
1774 |
-
radiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;
|
1775 |
-
radiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;
|
1776 |
-
|
1777 |
-
this.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;
|
1778 |
-
|
1779 |
-
//this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])
|
1780 |
-
this.setCenterPoint(radiusReductionLeft, radiusReductionRight);
|
1781 |
-
|
1782 |
-
},
|
1783 |
-
setCenterPoint: function(leftMovement, rightMovement){
|
1784 |
-
|
1785 |
-
var maxRight = this.width - rightMovement - this.drawingArea,
|
1786 |
-
maxLeft = leftMovement + this.drawingArea;
|
1787 |
-
|
1788 |
-
this.xCenter = (maxLeft + maxRight)/2;
|
1789 |
-
// Always vertically in the centre as the text height doesn't change
|
1790 |
-
this.yCenter = (this.height/2);
|
1791 |
-
},
|
1792 |
-
|
1793 |
-
getIndexAngle : function(index){
|
1794 |
-
var angleMultiplier = (Math.PI * 2) / this.valuesCount;
|
1795 |
-
// Start from the top instead of right, so remove a quarter of the circle
|
1796 |
-
|
1797 |
-
return index * angleMultiplier - (Math.PI/2);
|
1798 |
-
},
|
1799 |
-
getPointPosition : function(index, distanceFromCenter){
|
1800 |
-
var thisAngle = this.getIndexAngle(index);
|
1801 |
-
return {
|
1802 |
-
x : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,
|
1803 |
-
y : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter
|
1804 |
-
};
|
1805 |
-
},
|
1806 |
-
draw: function(){
|
1807 |
-
if (this.display){
|
1808 |
-
var ctx = this.ctx;
|
1809 |
-
each(this.yLabels, function(label, index){
|
1810 |
-
// Don't draw a centre value
|
1811 |
-
if (index > 0){
|
1812 |
-
var yCenterOffset = index * (this.drawingArea/this.steps),
|
1813 |
-
yHeight = this.yCenter - yCenterOffset,
|
1814 |
-
pointPosition;
|
1815 |
-
|
1816 |
-
// Draw circular lines around the scale
|
1817 |
-
if (this.lineWidth > 0){
|
1818 |
-
ctx.strokeStyle = this.lineColor;
|
1819 |
-
ctx.lineWidth = this.lineWidth;
|
1820 |
-
|
1821 |
-
if(this.lineArc){
|
1822 |
-
ctx.beginPath();
|
1823 |
-
ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);
|
1824 |
-
ctx.closePath();
|
1825 |
-
ctx.stroke();
|
1826 |
-
} else{
|
1827 |
-
ctx.beginPath();
|
1828 |
-
for (var i=0;i<this.valuesCount;i++)
|
1829 |
-
{
|
1830 |
-
pointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));
|
1831 |
-
if (i === 0){
|
1832 |
-
ctx.moveTo(pointPosition.x, pointPosition.y);
|
1833 |
-
} else {
|
1834 |
-
ctx.lineTo(pointPosition.x, pointPosition.y);
|
1835 |
-
}
|
1836 |
-
}
|
1837 |
-
ctx.closePath();
|
1838 |
-
ctx.stroke();
|
1839 |
-
}
|
1840 |
-
}
|
1841 |
-
if(this.showLabels){
|
1842 |
-
ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
|
1843 |
-
if (this.showLabelBackdrop){
|
1844 |
-
var labelWidth = ctx.measureText(label).width;
|
1845 |
-
ctx.fillStyle = this.backdropColor;
|
1846 |
-
ctx.fillRect(
|
1847 |
-
this.xCenter - labelWidth/2 - this.backdropPaddingX,
|
1848 |
-
yHeight - this.fontSize/2 - this.backdropPaddingY,
|
1849 |
-
labelWidth + this.backdropPaddingX*2,
|
1850 |
-
this.fontSize + this.backdropPaddingY*2
|
1851 |
-
);
|
1852 |
-
}
|
1853 |
-
ctx.textAlign = 'center';
|
1854 |
-
ctx.textBaseline = "middle";
|
1855 |
-
ctx.fillStyle = this.fontColor;
|
1856 |
-
ctx.fillText(label, this.xCenter, yHeight);
|
1857 |
-
}
|
1858 |
-
}
|
1859 |
-
}, this);
|
1860 |
-
|
1861 |
-
if (!this.lineArc){
|
1862 |
-
ctx.lineWidth = this.angleLineWidth;
|
1863 |
-
ctx.strokeStyle = this.angleLineColor;
|
1864 |
-
for (var i = this.valuesCount - 1; i >= 0; i--) {
|
1865 |
-
if (this.angleLineWidth > 0){
|
1866 |
-
var outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max));
|
1867 |
-
ctx.beginPath();
|
1868 |
-
ctx.moveTo(this.xCenter, this.yCenter);
|
1869 |
-
ctx.lineTo(outerPosition.x, outerPosition.y);
|
1870 |
-
ctx.stroke();
|
1871 |
-
ctx.closePath();
|
1872 |
-
}
|
1873 |
-
// Extra 3px out for some label spacing
|
1874 |
-
var pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5);
|
1875 |
-
ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
|
1876 |
-
ctx.fillStyle = this.pointLabelFontColor;
|
1877 |
-
|
1878 |
-
var labelsCount = this.labels.length,
|
1879 |
-
halfLabelsCount = this.labels.length/2,
|
1880 |
-
quarterLabelsCount = halfLabelsCount/2,
|
1881 |
-
upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
|
1882 |
-
exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
|
1883 |
-
if (i === 0){
|
1884 |
-
ctx.textAlign = 'center';
|
1885 |
-
} else if(i === halfLabelsCount){
|
1886 |
-
ctx.textAlign = 'center';
|
1887 |
-
} else if (i < halfLabelsCount){
|
1888 |
-
ctx.textAlign = 'left';
|
1889 |
-
} else {
|
1890 |
-
ctx.textAlign = 'right';
|
1891 |
-
}
|
1892 |
-
|
1893 |
-
// Set the correct text baseline based on outer positioning
|
1894 |
-
if (exactQuarter){
|
1895 |
-
ctx.textBaseline = 'middle';
|
1896 |
-
} else if (upperHalf){
|
1897 |
-
ctx.textBaseline = 'bottom';
|
1898 |
-
} else {
|
1899 |
-
ctx.textBaseline = 'top';
|
1900 |
-
}
|
1901 |
-
|
1902 |
-
ctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);
|
1903 |
-
}
|
1904 |
-
}
|
1905 |
-
}
|
1906 |
-
}
|
1907 |
-
});
|
1908 |
-
|
1909 |
-
// Attach global event to resize each chart instance when the browser resizes
|
1910 |
-
helpers.addEvent(window, "resize", (function(){
|
1911 |
-
// Basic debounce of resize function so it doesn't hurt performance when resizing browser.
|
1912 |
-
var timeout;
|
1913 |
-
return function(){
|
1914 |
-
clearTimeout(timeout);
|
1915 |
-
timeout = setTimeout(function(){
|
1916 |
-
each(Chart.instances,function(instance){
|
1917 |
-
// If the responsive flag is set in the chart instance config
|
1918 |
-
// Cascade the resize event down to the chart.
|
1919 |
-
if (instance.options.responsive){
|
1920 |
-
instance.resize(instance.render, true);
|
1921 |
-
}
|
1922 |
-
});
|
1923 |
-
}, 50);
|
1924 |
-
};
|
1925 |
-
})());
|
1926 |
-
|
1927 |
-
|
1928 |
-
if (amd) {
|
1929 |
-
define(function(){
|
1930 |
-
return Chart;
|
1931 |
-
});
|
1932 |
-
} else if (typeof module === 'object' && module.exports) {
|
1933 |
-
module.exports = Chart;
|
1934 |
-
}
|
1935 |
-
|
1936 |
-
root.Chart = Chart;
|
1937 |
-
|
1938 |
-
Chart.noConflict = function(){
|
1939 |
-
root.Chart = previous;
|
1940 |
-
return Chart;
|
1941 |
-
};
|
1942 |
-
|
1943 |
-
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/src/Chart.Doughnut.js
DELETED
@@ -1,184 +0,0 @@
|
|
1 |
-
(function(){
|
2 |
-
"use strict";
|
3 |
-
|
4 |
-
var root = this,
|
5 |
-
Chart = root.Chart,
|
6 |
-
//Cache a local reference to Chart.helpers
|
7 |
-
helpers = Chart.helpers;
|
8 |
-
|
9 |
-
var defaultConfig = {
|
10 |
-
//Boolean - Whether we should show a stroke on each segment
|
11 |
-
segmentShowStroke : true,
|
12 |
-
|
13 |
-
//String - The colour of each segment stroke
|
14 |
-
segmentStrokeColor : "#fff",
|
15 |
-
|
16 |
-
//Number - The width of each segment stroke
|
17 |
-
segmentStrokeWidth : 2,
|
18 |
-
|
19 |
-
//The percentage of the chart that we cut out of the middle.
|
20 |
-
percentageInnerCutout : 50,
|
21 |
-
|
22 |
-
//Number - Amount of animation steps
|
23 |
-
animationSteps : 100,
|
24 |
-
|
25 |
-
//String - Animation easing effect
|
26 |
-
animationEasing : "easeOutBounce",
|
27 |
-
|
28 |
-
//Boolean - Whether we animate the rotation of the Doughnut
|
29 |
-
animateRotate : true,
|
30 |
-
|
31 |
-
//Boolean - Whether we animate scaling the Doughnut from the centre
|
32 |
-
animateScale : false,
|
33 |
-
|
34 |
-
//String - A legend template
|
35 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
|
36 |
-
|
37 |
-
};
|
38 |
-
|
39 |
-
|
40 |
-
Chart.Type.extend({
|
41 |
-
//Passing in a name registers this chart in the Chart namespace
|
42 |
-
name: "Doughnut",
|
43 |
-
//Providing a defaults will also register the deafults in the chart namespace
|
44 |
-
defaults : defaultConfig,
|
45 |
-
//Initialize is fired when the chart is initialized - Data is passed in as a parameter
|
46 |
-
//Config is automatically merged by the core of Chart.js, and is available at this.options
|
47 |
-
initialize: function(data){
|
48 |
-
|
49 |
-
//Declare segments as a static property to prevent inheriting across the Chart type prototype
|
50 |
-
this.segments = [];
|
51 |
-
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
|
52 |
-
|
53 |
-
this.SegmentArc = Chart.Arc.extend({
|
54 |
-
ctx : this.chart.ctx,
|
55 |
-
x : this.chart.width/2,
|
56 |
-
y : this.chart.height/2
|
57 |
-
});
|
58 |
-
|
59 |
-
//Set up tooltip events on the chart
|
60 |
-
if (this.options.showTooltips){
|
61 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
62 |
-
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
|
63 |
-
|
64 |
-
helpers.each(this.segments,function(segment){
|
65 |
-
segment.restore(["fillColor"]);
|
66 |
-
});
|
67 |
-
helpers.each(activeSegments,function(activeSegment){
|
68 |
-
activeSegment.fillColor = activeSegment.highlightColor;
|
69 |
-
});
|
70 |
-
this.showTooltip(activeSegments);
|
71 |
-
});
|
72 |
-
}
|
73 |
-
this.calculateTotal(data);
|
74 |
-
|
75 |
-
helpers.each(data,function(datapoint, index){
|
76 |
-
this.addData(datapoint, index, true);
|
77 |
-
},this);
|
78 |
-
|
79 |
-
this.render();
|
80 |
-
},
|
81 |
-
getSegmentsAtEvent : function(e){
|
82 |
-
var segmentsArray = [];
|
83 |
-
|
84 |
-
var location = helpers.getRelativePosition(e);
|
85 |
-
|
86 |
-
helpers.each(this.segments,function(segment){
|
87 |
-
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
|
88 |
-
},this);
|
89 |
-
return segmentsArray;
|
90 |
-
},
|
91 |
-
addData : function(segment, atIndex, silent){
|
92 |
-
var index = atIndex || this.segments.length;
|
93 |
-
this.segments.splice(index, 0, new this.SegmentArc({
|
94 |
-
value : segment.value,
|
95 |
-
outerRadius : (this.options.animateScale) ? 0 : this.outerRadius,
|
96 |
-
innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,
|
97 |
-
fillColor : segment.color,
|
98 |
-
highlightColor : segment.highlight || segment.color,
|
99 |
-
showStroke : this.options.segmentShowStroke,
|
100 |
-
strokeWidth : this.options.segmentStrokeWidth,
|
101 |
-
strokeColor : this.options.segmentStrokeColor,
|
102 |
-
startAngle : Math.PI * 1.5,
|
103 |
-
circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),
|
104 |
-
label : segment.label
|
105 |
-
}));
|
106 |
-
if (!silent){
|
107 |
-
this.reflow();
|
108 |
-
this.update();
|
109 |
-
}
|
110 |
-
},
|
111 |
-
calculateCircumference : function(value){
|
112 |
-
return (Math.PI*2)*(value / this.total);
|
113 |
-
},
|
114 |
-
calculateTotal : function(data){
|
115 |
-
this.total = 0;
|
116 |
-
helpers.each(data,function(segment){
|
117 |
-
this.total += segment.value;
|
118 |
-
},this);
|
119 |
-
},
|
120 |
-
update : function(){
|
121 |
-
this.calculateTotal(this.segments);
|
122 |
-
|
123 |
-
// Reset any highlight colours before updating.
|
124 |
-
helpers.each(this.activeElements, function(activeElement){
|
125 |
-
activeElement.restore(['fillColor']);
|
126 |
-
});
|
127 |
-
|
128 |
-
helpers.each(this.segments,function(segment){
|
129 |
-
segment.save();
|
130 |
-
});
|
131 |
-
this.render();
|
132 |
-
},
|
133 |
-
|
134 |
-
removeData: function(atIndex){
|
135 |
-
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
|
136 |
-
this.segments.splice(indexToDelete, 1);
|
137 |
-
this.reflow();
|
138 |
-
this.update();
|
139 |
-
},
|
140 |
-
|
141 |
-
reflow : function(){
|
142 |
-
helpers.extend(this.SegmentArc.prototype,{
|
143 |
-
x : this.chart.width/2,
|
144 |
-
y : this.chart.height/2
|
145 |
-
});
|
146 |
-
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
|
147 |
-
helpers.each(this.segments, function(segment){
|
148 |
-
segment.update({
|
149 |
-
outerRadius : this.outerRadius,
|
150 |
-
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
|
151 |
-
});
|
152 |
-
}, this);
|
153 |
-
},
|
154 |
-
draw : function(easeDecimal){
|
155 |
-
var animDecimal = (easeDecimal) ? easeDecimal : 1;
|
156 |
-
this.clear();
|
157 |
-
helpers.each(this.segments,function(segment,index){
|
158 |
-
segment.transition({
|
159 |
-
circumference : this.calculateCircumference(segment.value),
|
160 |
-
outerRadius : this.outerRadius,
|
161 |
-
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
|
162 |
-
},animDecimal);
|
163 |
-
|
164 |
-
segment.endAngle = segment.startAngle + segment.circumference;
|
165 |
-
|
166 |
-
segment.draw();
|
167 |
-
if (index === 0){
|
168 |
-
segment.startAngle = Math.PI * 1.5;
|
169 |
-
}
|
170 |
-
//Check to see if it's the last segment, if not get the next and update the start angle
|
171 |
-
if (index < this.segments.length-1){
|
172 |
-
this.segments[index+1].startAngle = segment.endAngle;
|
173 |
-
}
|
174 |
-
},this);
|
175 |
-
|
176 |
-
}
|
177 |
-
});
|
178 |
-
|
179 |
-
Chart.types.Doughnut.extend({
|
180 |
-
name : "Pie",
|
181 |
-
defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})
|
182 |
-
});
|
183 |
-
|
184 |
-
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/src/Chart.Line.js
DELETED
@@ -1,366 +0,0 @@
|
|
1 |
-
(function(){
|
2 |
-
"use strict";
|
3 |
-
|
4 |
-
var root = this,
|
5 |
-
Chart = root.Chart,
|
6 |
-
helpers = Chart.helpers;
|
7 |
-
|
8 |
-
var defaultConfig = {
|
9 |
-
|
10 |
-
///Boolean - Whether grid lines are shown across the chart
|
11 |
-
scaleShowGridLines : true,
|
12 |
-
|
13 |
-
//String - Colour of the grid lines
|
14 |
-
scaleGridLineColor : "rgba(0,0,0,.05)",
|
15 |
-
|
16 |
-
//Number - Width of the grid lines
|
17 |
-
scaleGridLineWidth : 1,
|
18 |
-
|
19 |
-
//Boolean - Whether the line is curved between points
|
20 |
-
bezierCurve : true,
|
21 |
-
|
22 |
-
//Number - Tension of the bezier curve between points
|
23 |
-
bezierCurveTension : 0.4,
|
24 |
-
|
25 |
-
//Boolean - Whether to show a dot for each point
|
26 |
-
pointDot : true,
|
27 |
-
|
28 |
-
//Number - Radius of each point dot in pixels
|
29 |
-
pointDotRadius : 4,
|
30 |
-
|
31 |
-
//Number - Pixel width of point dot stroke
|
32 |
-
pointDotStrokeWidth : 1,
|
33 |
-
|
34 |
-
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
35 |
-
pointHitDetectionRadius : 20,
|
36 |
-
|
37 |
-
//Boolean - Whether to show a stroke for datasets
|
38 |
-
datasetStroke : true,
|
39 |
-
|
40 |
-
//Number - Pixel width of dataset stroke
|
41 |
-
datasetStrokeWidth : 2,
|
42 |
-
|
43 |
-
//Boolean - Whether to fill the dataset with a colour
|
44 |
-
datasetFill : true,
|
45 |
-
|
46 |
-
//String - A legend template
|
47 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
48 |
-
|
49 |
-
};
|
50 |
-
|
51 |
-
|
52 |
-
Chart.Type.extend({
|
53 |
-
name: "Line",
|
54 |
-
defaults : defaultConfig,
|
55 |
-
initialize: function(data){
|
56 |
-
//Declare the extension of the default point, to cater for the options passed in to the constructor
|
57 |
-
this.PointClass = Chart.Point.extend({
|
58 |
-
strokeWidth : this.options.pointDotStrokeWidth,
|
59 |
-
radius : this.options.pointDotRadius,
|
60 |
-
display: this.options.pointDot,
|
61 |
-
hitDetectionRadius : this.options.pointHitDetectionRadius,
|
62 |
-
ctx : this.chart.ctx,
|
63 |
-
inRange : function(mouseX){
|
64 |
-
return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));
|
65 |
-
}
|
66 |
-
});
|
67 |
-
|
68 |
-
this.datasets = [];
|
69 |
-
|
70 |
-
//Set up tooltip events on the chart
|
71 |
-
if (this.options.showTooltips){
|
72 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
73 |
-
var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
|
74 |
-
this.eachPoints(function(point){
|
75 |
-
point.restore(['fillColor', 'strokeColor']);
|
76 |
-
});
|
77 |
-
helpers.each(activePoints, function(activePoint){
|
78 |
-
activePoint.fillColor = activePoint.highlightFill;
|
79 |
-
activePoint.strokeColor = activePoint.highlightStroke;
|
80 |
-
});
|
81 |
-
this.showTooltip(activePoints);
|
82 |
-
});
|
83 |
-
}
|
84 |
-
|
85 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
86 |
-
helpers.each(data.datasets,function(dataset){
|
87 |
-
|
88 |
-
var datasetObject = {
|
89 |
-
label : dataset.label || null,
|
90 |
-
fillColor : dataset.fillColor,
|
91 |
-
strokeColor : dataset.strokeColor,
|
92 |
-
pointColor : dataset.pointColor,
|
93 |
-
pointStrokeColor : dataset.pointStrokeColor,
|
94 |
-
points : []
|
95 |
-
};
|
96 |
-
|
97 |
-
this.datasets.push(datasetObject);
|
98 |
-
|
99 |
-
|
100 |
-
helpers.each(dataset.data,function(dataPoint,index){
|
101 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
102 |
-
datasetObject.points.push(new this.PointClass({
|
103 |
-
value : dataPoint,
|
104 |
-
label : data.labels[index],
|
105 |
-
datasetLabel: dataset.label,
|
106 |
-
strokeColor : dataset.pointStrokeColor,
|
107 |
-
fillColor : dataset.pointColor,
|
108 |
-
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
109 |
-
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
110 |
-
}));
|
111 |
-
},this);
|
112 |
-
|
113 |
-
this.buildScale(data.labels);
|
114 |
-
|
115 |
-
|
116 |
-
this.eachPoints(function(point, index){
|
117 |
-
helpers.extend(point, {
|
118 |
-
x: this.scale.calculateX(index),
|
119 |
-
y: this.scale.endPoint
|
120 |
-
});
|
121 |
-
point.save();
|
122 |
-
}, this);
|
123 |
-
|
124 |
-
},this);
|
125 |
-
|
126 |
-
|
127 |
-
this.render();
|
128 |
-
},
|
129 |
-
update : function(){
|
130 |
-
this.scale.update();
|
131 |
-
// Reset any highlight colours before updating.
|
132 |
-
helpers.each(this.activeElements, function(activeElement){
|
133 |
-
activeElement.restore(['fillColor', 'strokeColor']);
|
134 |
-
});
|
135 |
-
this.eachPoints(function(point){
|
136 |
-
point.save();
|
137 |
-
});
|
138 |
-
this.render();
|
139 |
-
},
|
140 |
-
eachPoints : function(callback){
|
141 |
-
helpers.each(this.datasets,function(dataset){
|
142 |
-
helpers.each(dataset.points,callback,this);
|
143 |
-
},this);
|
144 |
-
},
|
145 |
-
getPointsAtEvent : function(e){
|
146 |
-
var pointsArray = [],
|
147 |
-
eventPosition = helpers.getRelativePosition(e);
|
148 |
-
helpers.each(this.datasets,function(dataset){
|
149 |
-
helpers.each(dataset.points,function(point){
|
150 |
-
if (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);
|
151 |
-
});
|
152 |
-
},this);
|
153 |
-
return pointsArray;
|
154 |
-
},
|
155 |
-
buildScale : function(labels){
|
156 |
-
var self = this;
|
157 |
-
|
158 |
-
var dataTotal = function(){
|
159 |
-
var values = [];
|
160 |
-
self.eachPoints(function(point){
|
161 |
-
values.push(point.value);
|
162 |
-
});
|
163 |
-
|
164 |
-
return values;
|
165 |
-
};
|
166 |
-
|
167 |
-
var scaleOptions = {
|
168 |
-
templateString : this.options.scaleLabel,
|
169 |
-
height : this.chart.height,
|
170 |
-
width : this.chart.width,
|
171 |
-
ctx : this.chart.ctx,
|
172 |
-
textColor : this.options.scaleFontColor,
|
173 |
-
fontSize : this.options.scaleFontSize,
|
174 |
-
fontStyle : this.options.scaleFontStyle,
|
175 |
-
fontFamily : this.options.scaleFontFamily,
|
176 |
-
valuesCount : labels.length,
|
177 |
-
beginAtZero : this.options.scaleBeginAtZero,
|
178 |
-
integersOnly : this.options.scaleIntegersOnly,
|
179 |
-
calculateYRange : function(currentHeight){
|
180 |
-
var updatedRanges = helpers.calculateScaleRange(
|
181 |
-
dataTotal(),
|
182 |
-
currentHeight,
|
183 |
-
this.fontSize,
|
184 |
-
this.beginAtZero,
|
185 |
-
this.integersOnly
|
186 |
-
);
|
187 |
-
helpers.extend(this, updatedRanges);
|
188 |
-
},
|
189 |
-
xLabels : labels,
|
190 |
-
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
191 |
-
lineWidth : this.options.scaleLineWidth,
|
192 |
-
lineColor : this.options.scaleLineColor,
|
193 |
-
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
194 |
-
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
195 |
-
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
|
196 |
-
showLabels : this.options.scaleShowLabels,
|
197 |
-
display : this.options.showScale
|
198 |
-
};
|
199 |
-
|
200 |
-
if (this.options.scaleOverride){
|
201 |
-
helpers.extend(scaleOptions, {
|
202 |
-
calculateYRange: helpers.noop,
|
203 |
-
steps: this.options.scaleSteps,
|
204 |
-
stepValue: this.options.scaleStepWidth,
|
205 |
-
min: this.options.scaleStartValue,
|
206 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
207 |
-
});
|
208 |
-
}
|
209 |
-
|
210 |
-
|
211 |
-
this.scale = new Chart.Scale(scaleOptions);
|
212 |
-
},
|
213 |
-
addData : function(valuesArray,label){
|
214 |
-
//Map the values array for each of the datasets
|
215 |
-
|
216 |
-
helpers.each(valuesArray,function(value,datasetIndex){
|
217 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
218 |
-
this.datasets[datasetIndex].points.push(new this.PointClass({
|
219 |
-
value : value,
|
220 |
-
label : label,
|
221 |
-
x: this.scale.calculateX(this.scale.valuesCount+1),
|
222 |
-
y: this.scale.endPoint,
|
223 |
-
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
|
224 |
-
fillColor : this.datasets[datasetIndex].pointColor
|
225 |
-
}));
|
226 |
-
},this);
|
227 |
-
|
228 |
-
this.scale.addXLabel(label);
|
229 |
-
//Then re-render the chart.
|
230 |
-
this.update();
|
231 |
-
},
|
232 |
-
removeData : function(){
|
233 |
-
this.scale.removeXLabel();
|
234 |
-
//Then re-render the chart.
|
235 |
-
helpers.each(this.datasets,function(dataset){
|
236 |
-
dataset.points.shift();
|
237 |
-
},this);
|
238 |
-
this.update();
|
239 |
-
},
|
240 |
-
reflow : function(){
|
241 |
-
var newScaleProps = helpers.extend({
|
242 |
-
height : this.chart.height,
|
243 |
-
width : this.chart.width
|
244 |
-
});
|
245 |
-
this.scale.update(newScaleProps);
|
246 |
-
},
|
247 |
-
draw : function(ease){
|
248 |
-
var easingDecimal = ease || 1;
|
249 |
-
this.clear();
|
250 |
-
|
251 |
-
var ctx = this.chart.ctx;
|
252 |
-
|
253 |
-
// Some helper methods for getting the next/prev points
|
254 |
-
var hasValue = function(item){
|
255 |
-
return item.value !== null;
|
256 |
-
},
|
257 |
-
nextPoint = function(point, collection, index){
|
258 |
-
return helpers.findNextWhere(collection, hasValue, index) || point;
|
259 |
-
},
|
260 |
-
previousPoint = function(point, collection, index){
|
261 |
-
return helpers.findPreviousWhere(collection, hasValue, index) || point;
|
262 |
-
};
|
263 |
-
|
264 |
-
this.scale.draw(easingDecimal);
|
265 |
-
|
266 |
-
|
267 |
-
helpers.each(this.datasets,function(dataset){
|
268 |
-
var pointsWithValues = helpers.where(dataset.points, hasValue);
|
269 |
-
|
270 |
-
//Transition each point first so that the line and point drawing isn't out of sync
|
271 |
-
//We can use this extra loop to calculate the control points of this dataset also in this loop
|
272 |
-
|
273 |
-
helpers.each(dataset.points, function(point, index){
|
274 |
-
if (point.hasValue()){
|
275 |
-
point.transition({
|
276 |
-
y : this.scale.calculateY(point.value),
|
277 |
-
x : this.scale.calculateX(index)
|
278 |
-
}, easingDecimal);
|
279 |
-
}
|
280 |
-
},this);
|
281 |
-
|
282 |
-
|
283 |
-
// Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point
|
284 |
-
// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed
|
285 |
-
if (this.options.bezierCurve){
|
286 |
-
helpers.each(pointsWithValues, function(point, index){
|
287 |
-
var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;
|
288 |
-
point.controlPoints = helpers.splineCurve(
|
289 |
-
previousPoint(point, pointsWithValues, index),
|
290 |
-
point,
|
291 |
-
nextPoint(point, pointsWithValues, index),
|
292 |
-
tension
|
293 |
-
);
|
294 |
-
|
295 |
-
// Prevent the bezier going outside of the bounds of the graph
|
296 |
-
|
297 |
-
// Cap puter bezier handles to the upper/lower scale bounds
|
298 |
-
if (point.controlPoints.outer.y > this.scale.endPoint){
|
299 |
-
point.controlPoints.outer.y = this.scale.endPoint;
|
300 |
-
}
|
301 |
-
else if (point.controlPoints.outer.y < this.scale.startPoint){
|
302 |
-
point.controlPoints.outer.y = this.scale.startPoint;
|
303 |
-
}
|
304 |
-
|
305 |
-
// Cap inner bezier handles to the upper/lower scale bounds
|
306 |
-
if (point.controlPoints.inner.y > this.scale.endPoint){
|
307 |
-
point.controlPoints.inner.y = this.scale.endPoint;
|
308 |
-
}
|
309 |
-
else if (point.controlPoints.inner.y < this.scale.startPoint){
|
310 |
-
point.controlPoints.inner.y = this.scale.startPoint;
|
311 |
-
}
|
312 |
-
},this);
|
313 |
-
}
|
314 |
-
|
315 |
-
|
316 |
-
//Draw the line between all the points
|
317 |
-
ctx.lineWidth = this.options.datasetStrokeWidth;
|
318 |
-
ctx.strokeStyle = dataset.strokeColor;
|
319 |
-
ctx.beginPath();
|
320 |
-
|
321 |
-
helpers.each(pointsWithValues, function(point, index){
|
322 |
-
if (index === 0){
|
323 |
-
ctx.moveTo(point.x, point.y);
|
324 |
-
}
|
325 |
-
else{
|
326 |
-
if(this.options.bezierCurve){
|
327 |
-
var previous = previousPoint(point, pointsWithValues, index);
|
328 |
-
|
329 |
-
ctx.bezierCurveTo(
|
330 |
-
previous.controlPoints.outer.x,
|
331 |
-
previous.controlPoints.outer.y,
|
332 |
-
point.controlPoints.inner.x,
|
333 |
-
point.controlPoints.inner.y,
|
334 |
-
point.x,
|
335 |
-
point.y
|
336 |
-
);
|
337 |
-
}
|
338 |
-
else{
|
339 |
-
ctx.lineTo(point.x,point.y);
|
340 |
-
}
|
341 |
-
}
|
342 |
-
}, this);
|
343 |
-
|
344 |
-
ctx.stroke();
|
345 |
-
|
346 |
-
if (this.options.datasetFill && pointsWithValues.length > 0){
|
347 |
-
//Round off the line by going to the base of the chart, back to the start, then fill.
|
348 |
-
ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);
|
349 |
-
ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);
|
350 |
-
ctx.fillStyle = dataset.fillColor;
|
351 |
-
ctx.closePath();
|
352 |
-
ctx.fill();
|
353 |
-
}
|
354 |
-
|
355 |
-
//Now draw the points over the line
|
356 |
-
//A little inefficient double looping, but better than the line
|
357 |
-
//lagging behind the point positions
|
358 |
-
helpers.each(pointsWithValues,function(point){
|
359 |
-
point.draw();
|
360 |
-
});
|
361 |
-
},this);
|
362 |
-
}
|
363 |
-
});
|
364 |
-
|
365 |
-
|
366 |
-
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/src/Chart.PolarArea.js
DELETED
@@ -1,248 +0,0 @@
|
|
1 |
-
(function(){
|
2 |
-
"use strict";
|
3 |
-
|
4 |
-
var root = this,
|
5 |
-
Chart = root.Chart,
|
6 |
-
//Cache a local reference to Chart.helpers
|
7 |
-
helpers = Chart.helpers;
|
8 |
-
|
9 |
-
var defaultConfig = {
|
10 |
-
//Boolean - Show a backdrop to the scale label
|
11 |
-
scaleShowLabelBackdrop : true,
|
12 |
-
|
13 |
-
//String - The colour of the label backdrop
|
14 |
-
scaleBackdropColor : "rgba(255,255,255,0.75)",
|
15 |
-
|
16 |
-
// Boolean - Whether the scale should begin at zero
|
17 |
-
scaleBeginAtZero : true,
|
18 |
-
|
19 |
-
//Number - The backdrop padding above & below the label in pixels
|
20 |
-
scaleBackdropPaddingY : 2,
|
21 |
-
|
22 |
-
//Number - The backdrop padding to the side of the label in pixels
|
23 |
-
scaleBackdropPaddingX : 2,
|
24 |
-
|
25 |
-
//Boolean - Show line for each value in the scale
|
26 |
-
scaleShowLine : true,
|
27 |
-
|
28 |
-
//Boolean - Stroke a line around each segment in the chart
|
29 |
-
segmentShowStroke : true,
|
30 |
-
|
31 |
-
//String - The colour of the stroke on each segement.
|
32 |
-
segmentStrokeColor : "#fff",
|
33 |
-
|
34 |
-
//Number - The width of the stroke value in pixels
|
35 |
-
segmentStrokeWidth : 2,
|
36 |
-
|
37 |
-
//Number - Amount of animation steps
|
38 |
-
animationSteps : 100,
|
39 |
-
|
40 |
-
//String - Animation easing effect.
|
41 |
-
animationEasing : "easeOutBounce",
|
42 |
-
|
43 |
-
//Boolean - Whether to animate the rotation of the chart
|
44 |
-
animateRotate : true,
|
45 |
-
|
46 |
-
//Boolean - Whether to animate scaling the chart from the centre
|
47 |
-
animateScale : false,
|
48 |
-
|
49 |
-
//String - A legend template
|
50 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
|
51 |
-
};
|
52 |
-
|
53 |
-
|
54 |
-
Chart.Type.extend({
|
55 |
-
//Passing in a name registers this chart in the Chart namespace
|
56 |
-
name: "PolarArea",
|
57 |
-
//Providing a defaults will also register the deafults in the chart namespace
|
58 |
-
defaults : defaultConfig,
|
59 |
-
//Initialize is fired when the chart is initialized - Data is passed in as a parameter
|
60 |
-
//Config is automatically merged by the core of Chart.js, and is available at this.options
|
61 |
-
initialize: function(data){
|
62 |
-
this.segments = [];
|
63 |
-
//Declare segment class as a chart instance specific class, so it can share props for this instance
|
64 |
-
this.SegmentArc = Chart.Arc.extend({
|
65 |
-
showStroke : this.options.segmentShowStroke,
|
66 |
-
strokeWidth : this.options.segmentStrokeWidth,
|
67 |
-
strokeColor : this.options.segmentStrokeColor,
|
68 |
-
ctx : this.chart.ctx,
|
69 |
-
innerRadius : 0,
|
70 |
-
x : this.chart.width/2,
|
71 |
-
y : this.chart.height/2
|
72 |
-
});
|
73 |
-
this.scale = new Chart.RadialScale({
|
74 |
-
display: this.options.showScale,
|
75 |
-
fontStyle: this.options.scaleFontStyle,
|
76 |
-
fontSize: this.options.scaleFontSize,
|
77 |
-
fontFamily: this.options.scaleFontFamily,
|
78 |
-
fontColor: this.options.scaleFontColor,
|
79 |
-
showLabels: this.options.scaleShowLabels,
|
80 |
-
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
|
81 |
-
backdropColor: this.options.scaleBackdropColor,
|
82 |
-
backdropPaddingY : this.options.scaleBackdropPaddingY,
|
83 |
-
backdropPaddingX: this.options.scaleBackdropPaddingX,
|
84 |
-
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
|
85 |
-
lineColor: this.options.scaleLineColor,
|
86 |
-
lineArc: true,
|
87 |
-
width: this.chart.width,
|
88 |
-
height: this.chart.height,
|
89 |
-
xCenter: this.chart.width/2,
|
90 |
-
yCenter: this.chart.height/2,
|
91 |
-
ctx : this.chart.ctx,
|
92 |
-
templateString: this.options.scaleLabel,
|
93 |
-
valuesCount: data.length
|
94 |
-
});
|
95 |
-
|
96 |
-
this.updateScaleRange(data);
|
97 |
-
|
98 |
-
this.scale.update();
|
99 |
-
|
100 |
-
helpers.each(data,function(segment,index){
|
101 |
-
this.addData(segment,index,true);
|
102 |
-
},this);
|
103 |
-
|
104 |
-
//Set up tooltip events on the chart
|
105 |
-
if (this.options.showTooltips){
|
106 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
107 |
-
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
|
108 |
-
helpers.each(this.segments,function(segment){
|
109 |
-
segment.restore(["fillColor"]);
|
110 |
-
});
|
111 |
-
helpers.each(activeSegments,function(activeSegment){
|
112 |
-
activeSegment.fillColor = activeSegment.highlightColor;
|
113 |
-
});
|
114 |
-
this.showTooltip(activeSegments);
|
115 |
-
});
|
116 |
-
}
|
117 |
-
|
118 |
-
this.render();
|
119 |
-
},
|
120 |
-
getSegmentsAtEvent : function(e){
|
121 |
-
var segmentsArray = [];
|
122 |
-
|
123 |
-
var location = helpers.getRelativePosition(e);
|
124 |
-
|
125 |
-
helpers.each(this.segments,function(segment){
|
126 |
-
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
|
127 |
-
},this);
|
128 |
-
return segmentsArray;
|
129 |
-
},
|
130 |
-
addData : function(segment, atIndex, silent){
|
131 |
-
var index = atIndex || this.segments.length;
|
132 |
-
|
133 |
-
this.segments.splice(index, 0, new this.SegmentArc({
|
134 |
-
fillColor: segment.color,
|
135 |
-
highlightColor: segment.highlight || segment.color,
|
136 |
-
label: segment.label,
|
137 |
-
value: segment.value,
|
138 |
-
outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
|
139 |
-
circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
|
140 |
-
startAngle: Math.PI * 1.5
|
141 |
-
}));
|
142 |
-
if (!silent){
|
143 |
-
this.reflow();
|
144 |
-
this.update();
|
145 |
-
}
|
146 |
-
},
|
147 |
-
removeData: function(atIndex){
|
148 |
-
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
|
149 |
-
this.segments.splice(indexToDelete, 1);
|
150 |
-
this.reflow();
|
151 |
-
this.update();
|
152 |
-
},
|
153 |
-
calculateTotal: function(data){
|
154 |
-
this.total = 0;
|
155 |
-
helpers.each(data,function(segment){
|
156 |
-
this.total += segment.value;
|
157 |
-
},this);
|
158 |
-
this.scale.valuesCount = this.segments.length;
|
159 |
-
},
|
160 |
-
updateScaleRange: function(datapoints){
|
161 |
-
var valuesArray = [];
|
162 |
-
helpers.each(datapoints,function(segment){
|
163 |
-
valuesArray.push(segment.value);
|
164 |
-
});
|
165 |
-
|
166 |
-
var scaleSizes = (this.options.scaleOverride) ?
|
167 |
-
{
|
168 |
-
steps: this.options.scaleSteps,
|
169 |
-
stepValue: this.options.scaleStepWidth,
|
170 |
-
min: this.options.scaleStartValue,
|
171 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
172 |
-
} :
|
173 |
-
helpers.calculateScaleRange(
|
174 |
-
valuesArray,
|
175 |
-
helpers.min([this.chart.width, this.chart.height])/2,
|
176 |
-
this.options.scaleFontSize,
|
177 |
-
this.options.scaleBeginAtZero,
|
178 |
-
this.options.scaleIntegersOnly
|
179 |
-
);
|
180 |
-
|
181 |
-
helpers.extend(
|
182 |
-
this.scale,
|
183 |
-
scaleSizes,
|
184 |
-
{
|
185 |
-
size: helpers.min([this.chart.width, this.chart.height]),
|
186 |
-
xCenter: this.chart.width/2,
|
187 |
-
yCenter: this.chart.height/2
|
188 |
-
}
|
189 |
-
);
|
190 |
-
|
191 |
-
},
|
192 |
-
update : function(){
|
193 |
-
this.calculateTotal(this.segments);
|
194 |
-
|
195 |
-
helpers.each(this.segments,function(segment){
|
196 |
-
segment.save();
|
197 |
-
});
|
198 |
-
this.render();
|
199 |
-
},
|
200 |
-
reflow : function(){
|
201 |
-
helpers.extend(this.SegmentArc.prototype,{
|
202 |
-
x : this.chart.width/2,
|
203 |
-
y : this.chart.height/2
|
204 |
-
});
|
205 |
-
this.updateScaleRange(this.segments);
|
206 |
-
this.scale.update();
|
207 |
-
|
208 |
-
helpers.extend(this.scale,{
|
209 |
-
xCenter: this.chart.width/2,
|
210 |
-
yCenter: this.chart.height/2
|
211 |
-
});
|
212 |
-
|
213 |
-
helpers.each(this.segments, function(segment){
|
214 |
-
segment.update({
|
215 |
-
outerRadius : this.scale.calculateCenterOffset(segment.value)
|
216 |
-
});
|
217 |
-
}, this);
|
218 |
-
|
219 |
-
},
|
220 |
-
draw : function(ease){
|
221 |
-
var easingDecimal = ease || 1;
|
222 |
-
//Clear & draw the canvas
|
223 |
-
this.clear();
|
224 |
-
helpers.each(this.segments,function(segment, index){
|
225 |
-
segment.transition({
|
226 |
-
circumference : this.scale.getCircumference(),
|
227 |
-
outerRadius : this.scale.calculateCenterOffset(segment.value)
|
228 |
-
},easingDecimal);
|
229 |
-
|
230 |
-
segment.endAngle = segment.startAngle + segment.circumference;
|
231 |
-
|
232 |
-
// If we've removed the first segment we need to set the first one to
|
233 |
-
// start at the top.
|
234 |
-
if (index === 0){
|
235 |
-
segment.startAngle = Math.PI * 1.5;
|
236 |
-
}
|
237 |
-
|
238 |
-
//Check to see if it's the last segment, if not get the next and update the start angle
|
239 |
-
if (index < this.segments.length - 1){
|
240 |
-
this.segments[index+1].startAngle = segment.endAngle;
|
241 |
-
}
|
242 |
-
segment.draw();
|
243 |
-
}, this);
|
244 |
-
this.scale.draw();
|
245 |
-
}
|
246 |
-
});
|
247 |
-
|
248 |
-
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/src/Chart.Radar.js
DELETED
@@ -1,343 +0,0 @@
|
|
1 |
-
(function(){
|
2 |
-
"use strict";
|
3 |
-
|
4 |
-
var root = this,
|
5 |
-
Chart = root.Chart,
|
6 |
-
helpers = Chart.helpers;
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
Chart.Type.extend({
|
11 |
-
name: "Radar",
|
12 |
-
defaults:{
|
13 |
-
//Boolean - Whether to show lines for each scale point
|
14 |
-
scaleShowLine : true,
|
15 |
-
|
16 |
-
//Boolean - Whether we show the angle lines out of the radar
|
17 |
-
angleShowLineOut : true,
|
18 |
-
|
19 |
-
//Boolean - Whether to show labels on the scale
|
20 |
-
scaleShowLabels : false,
|
21 |
-
|
22 |
-
// Boolean - Whether the scale should begin at zero
|
23 |
-
scaleBeginAtZero : true,
|
24 |
-
|
25 |
-
//String - Colour of the angle line
|
26 |
-
angleLineColor : "rgba(0,0,0,.1)",
|
27 |
-
|
28 |
-
//Number - Pixel width of the angle line
|
29 |
-
angleLineWidth : 1,
|
30 |
-
|
31 |
-
//String - Point label font declaration
|
32 |
-
pointLabelFontFamily : "'Arial'",
|
33 |
-
|
34 |
-
//String - Point label font weight
|
35 |
-
pointLabelFontStyle : "normal",
|
36 |
-
|
37 |
-
//Number - Point label font size in pixels
|
38 |
-
pointLabelFontSize : 10,
|
39 |
-
|
40 |
-
//String - Point label font colour
|
41 |
-
pointLabelFontColor : "#666",
|
42 |
-
|
43 |
-
//Boolean - Whether to show a dot for each point
|
44 |
-
pointDot : true,
|
45 |
-
|
46 |
-
//Number - Radius of each point dot in pixels
|
47 |
-
pointDotRadius : 3,
|
48 |
-
|
49 |
-
//Number - Pixel width of point dot stroke
|
50 |
-
pointDotStrokeWidth : 1,
|
51 |
-
|
52 |
-
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
53 |
-
pointHitDetectionRadius : 20,
|
54 |
-
|
55 |
-
//Boolean - Whether to show a stroke for datasets
|
56 |
-
datasetStroke : true,
|
57 |
-
|
58 |
-
//Number - Pixel width of dataset stroke
|
59 |
-
datasetStrokeWidth : 2,
|
60 |
-
|
61 |
-
//Boolean - Whether to fill the dataset with a colour
|
62 |
-
datasetFill : true,
|
63 |
-
|
64 |
-
//String - A legend template
|
65 |
-
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
|
66 |
-
|
67 |
-
},
|
68 |
-
|
69 |
-
initialize: function(data){
|
70 |
-
this.PointClass = Chart.Point.extend({
|
71 |
-
strokeWidth : this.options.pointDotStrokeWidth,
|
72 |
-
radius : this.options.pointDotRadius,
|
73 |
-
display: this.options.pointDot,
|
74 |
-
hitDetectionRadius : this.options.pointHitDetectionRadius,
|
75 |
-
ctx : this.chart.ctx
|
76 |
-
});
|
77 |
-
|
78 |
-
this.datasets = [];
|
79 |
-
|
80 |
-
this.buildScale(data);
|
81 |
-
|
82 |
-
//Set up tooltip events on the chart
|
83 |
-
if (this.options.showTooltips){
|
84 |
-
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
85 |
-
var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
|
86 |
-
|
87 |
-
this.eachPoints(function(point){
|
88 |
-
point.restore(['fillColor', 'strokeColor']);
|
89 |
-
});
|
90 |
-
helpers.each(activePointsCollection, function(activePoint){
|
91 |
-
activePoint.fillColor = activePoint.highlightFill;
|
92 |
-
activePoint.strokeColor = activePoint.highlightStroke;
|
93 |
-
});
|
94 |
-
|
95 |
-
this.showTooltip(activePointsCollection);
|
96 |
-
});
|
97 |
-
}
|
98 |
-
|
99 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
100 |
-
helpers.each(data.datasets,function(dataset){
|
101 |
-
|
102 |
-
var datasetObject = {
|
103 |
-
label: dataset.label || null,
|
104 |
-
fillColor : dataset.fillColor,
|
105 |
-
strokeColor : dataset.strokeColor,
|
106 |
-
pointColor : dataset.pointColor,
|
107 |
-
pointStrokeColor : dataset.pointStrokeColor,
|
108 |
-
points : []
|
109 |
-
};
|
110 |
-
|
111 |
-
this.datasets.push(datasetObject);
|
112 |
-
|
113 |
-
helpers.each(dataset.data,function(dataPoint,index){
|
114 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
115 |
-
var pointPosition;
|
116 |
-
if (!this.scale.animation){
|
117 |
-
pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));
|
118 |
-
}
|
119 |
-
datasetObject.points.push(new this.PointClass({
|
120 |
-
value : dataPoint,
|
121 |
-
label : data.labels[index],
|
122 |
-
datasetLabel: dataset.label,
|
123 |
-
x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
|
124 |
-
y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
|
125 |
-
strokeColor : dataset.pointStrokeColor,
|
126 |
-
fillColor : dataset.pointColor,
|
127 |
-
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
128 |
-
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
129 |
-
}));
|
130 |
-
},this);
|
131 |
-
|
132 |
-
},this);
|
133 |
-
|
134 |
-
this.render();
|
135 |
-
},
|
136 |
-
eachPoints : function(callback){
|
137 |
-
helpers.each(this.datasets,function(dataset){
|
138 |
-
helpers.each(dataset.points,callback,this);
|
139 |
-
},this);
|
140 |
-
},
|
141 |
-
|
142 |
-
getPointsAtEvent : function(evt){
|
143 |
-
var mousePosition = helpers.getRelativePosition(evt),
|
144 |
-
fromCenter = helpers.getAngleFromPoint({
|
145 |
-
x: this.scale.xCenter,
|
146 |
-
y: this.scale.yCenter
|
147 |
-
}, mousePosition);
|
148 |
-
|
149 |
-
var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,
|
150 |
-
pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),
|
151 |
-
activePointsCollection = [];
|
152 |
-
|
153 |
-
// If we're at the top, make the pointIndex 0 to get the first of the array.
|
154 |
-
if (pointIndex >= this.scale.valuesCount || pointIndex < 0){
|
155 |
-
pointIndex = 0;
|
156 |
-
}
|
157 |
-
|
158 |
-
if (fromCenter.distance <= this.scale.drawingArea){
|
159 |
-
helpers.each(this.datasets, function(dataset){
|
160 |
-
activePointsCollection.push(dataset.points[pointIndex]);
|
161 |
-
});
|
162 |
-
}
|
163 |
-
|
164 |
-
return activePointsCollection;
|
165 |
-
},
|
166 |
-
|
167 |
-
buildScale : function(data){
|
168 |
-
this.scale = new Chart.RadialScale({
|
169 |
-
display: this.options.showScale,
|
170 |
-
fontStyle: this.options.scaleFontStyle,
|
171 |
-
fontSize: this.options.scaleFontSize,
|
172 |
-
fontFamily: this.options.scaleFontFamily,
|
173 |
-
fontColor: this.options.scaleFontColor,
|
174 |
-
showLabels: this.options.scaleShowLabels,
|
175 |
-
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
|
176 |
-
backdropColor: this.options.scaleBackdropColor,
|
177 |
-
backdropPaddingY : this.options.scaleBackdropPaddingY,
|
178 |
-
backdropPaddingX: this.options.scaleBackdropPaddingX,
|
179 |
-
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
|
180 |
-
lineColor: this.options.scaleLineColor,
|
181 |
-
angleLineColor : this.options.angleLineColor,
|
182 |
-
angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,
|
183 |
-
// Point labels at the edge of each line
|
184 |
-
pointLabelFontColor : this.options.pointLabelFontColor,
|
185 |
-
pointLabelFontSize : this.options.pointLabelFontSize,
|
186 |
-
pointLabelFontFamily : this.options.pointLabelFontFamily,
|
187 |
-
pointLabelFontStyle : this.options.pointLabelFontStyle,
|
188 |
-
height : this.chart.height,
|
189 |
-
width: this.chart.width,
|
190 |
-
xCenter: this.chart.width/2,
|
191 |
-
yCenter: this.chart.height/2,
|
192 |
-
ctx : this.chart.ctx,
|
193 |
-
templateString: this.options.scaleLabel,
|
194 |
-
labels: data.labels,
|
195 |
-
valuesCount: data.datasets[0].data.length
|
196 |
-
});
|
197 |
-
|
198 |
-
this.scale.setScaleSize();
|
199 |
-
this.updateScaleRange(data.datasets);
|
200 |
-
this.scale.buildYLabels();
|
201 |
-
},
|
202 |
-
updateScaleRange: function(datasets){
|
203 |
-
var valuesArray = (function(){
|
204 |
-
var totalDataArray = [];
|
205 |
-
helpers.each(datasets,function(dataset){
|
206 |
-
if (dataset.data){
|
207 |
-
totalDataArray = totalDataArray.concat(dataset.data);
|
208 |
-
}
|
209 |
-
else {
|
210 |
-
helpers.each(dataset.points, function(point){
|
211 |
-
totalDataArray.push(point.value);
|
212 |
-
});
|
213 |
-
}
|
214 |
-
});
|
215 |
-
return totalDataArray;
|
216 |
-
})();
|
217 |
-
|
218 |
-
|
219 |
-
var scaleSizes = (this.options.scaleOverride) ?
|
220 |
-
{
|
221 |
-
steps: this.options.scaleSteps,
|
222 |
-
stepValue: this.options.scaleStepWidth,
|
223 |
-
min: this.options.scaleStartValue,
|
224 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
225 |
-
} :
|
226 |
-
helpers.calculateScaleRange(
|
227 |
-
valuesArray,
|
228 |
-
helpers.min([this.chart.width, this.chart.height])/2,
|
229 |
-
this.options.scaleFontSize,
|
230 |
-
this.options.scaleBeginAtZero,
|
231 |
-
this.options.scaleIntegersOnly
|
232 |
-
);
|
233 |
-
|
234 |
-
helpers.extend(
|
235 |
-
this.scale,
|
236 |
-
scaleSizes
|
237 |
-
);
|
238 |
-
|
239 |
-
},
|
240 |
-
addData : function(valuesArray,label){
|
241 |
-
//Map the values array for each of the datasets
|
242 |
-
this.scale.valuesCount++;
|
243 |
-
helpers.each(valuesArray,function(value,datasetIndex){
|
244 |
-
var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));
|
245 |
-
this.datasets[datasetIndex].points.push(new this.PointClass({
|
246 |
-
value : value,
|
247 |
-
label : label,
|
248 |
-
x: pointPosition.x,
|
249 |
-
y: pointPosition.y,
|
250 |
-
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
|
251 |
-
fillColor : this.datasets[datasetIndex].pointColor
|
252 |
-
}));
|
253 |
-
},this);
|
254 |
-
|
255 |
-
this.scale.labels.push(label);
|
256 |
-
|
257 |
-
this.reflow();
|
258 |
-
|
259 |
-
this.update();
|
260 |
-
},
|
261 |
-
removeData : function(){
|
262 |
-
this.scale.valuesCount--;
|
263 |
-
this.scale.labels.shift();
|
264 |
-
helpers.each(this.datasets,function(dataset){
|
265 |
-
dataset.points.shift();
|
266 |
-
},this);
|
267 |
-
this.reflow();
|
268 |
-
this.update();
|
269 |
-
},
|
270 |
-
update : function(){
|
271 |
-
this.eachPoints(function(point){
|
272 |
-
point.save();
|
273 |
-
});
|
274 |
-
this.reflow();
|
275 |
-
this.render();
|
276 |
-
},
|
277 |
-
reflow: function(){
|
278 |
-
helpers.extend(this.scale, {
|
279 |
-
width : this.chart.width,
|
280 |
-
height: this.chart.height,
|
281 |
-
size : helpers.min([this.chart.width, this.chart.height]),
|
282 |
-
xCenter: this.chart.width/2,
|
283 |
-
yCenter: this.chart.height/2
|
284 |
-
});
|
285 |
-
this.updateScaleRange(this.datasets);
|
286 |
-
this.scale.setScaleSize();
|
287 |
-
this.scale.buildYLabels();
|
288 |
-
},
|
289 |
-
draw : function(ease){
|
290 |
-
var easeDecimal = ease || 1,
|
291 |
-
ctx = this.chart.ctx;
|
292 |
-
this.clear();
|
293 |
-
this.scale.draw();
|
294 |
-
|
295 |
-
helpers.each(this.datasets,function(dataset){
|
296 |
-
|
297 |
-
//Transition each point first so that the line and point drawing isn't out of sync
|
298 |
-
helpers.each(dataset.points,function(point,index){
|
299 |
-
if (point.hasValue()){
|
300 |
-
point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
|
301 |
-
}
|
302 |
-
},this);
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
//Draw the line between all the points
|
307 |
-
ctx.lineWidth = this.options.datasetStrokeWidth;
|
308 |
-
ctx.strokeStyle = dataset.strokeColor;
|
309 |
-
ctx.beginPath();
|
310 |
-
helpers.each(dataset.points,function(point,index){
|
311 |
-
if (index === 0){
|
312 |
-
ctx.moveTo(point.x,point.y);
|
313 |
-
}
|
314 |
-
else{
|
315 |
-
ctx.lineTo(point.x,point.y);
|
316 |
-
}
|
317 |
-
},this);
|
318 |
-
ctx.closePath();
|
319 |
-
ctx.stroke();
|
320 |
-
|
321 |
-
ctx.fillStyle = dataset.fillColor;
|
322 |
-
ctx.fill();
|
323 |
-
|
324 |
-
//Now draw the points over the line
|
325 |
-
//A little inefficient double looping, but better than the line
|
326 |
-
//lagging behind the point positions
|
327 |
-
helpers.each(dataset.points,function(point){
|
328 |
-
if (point.hasValue()){
|
329 |
-
point.draw();
|
330 |
-
}
|
331 |
-
});
|
332 |
-
|
333 |
-
},this);
|
334 |
-
|
335 |
-
}
|
336 |
-
|
337 |
-
});
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
}).call(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/Chart_js/utils.js
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
'use strict';
|
2 |
+
|
3 |
+
window.chartColors = {
|
4 |
+
red: 'rgb(255, 99, 132)',
|
5 |
+
orange: 'rgb(255, 159, 64)',
|
6 |
+
yellow: 'rgb(255, 205, 86)',
|
7 |
+
green: 'rgb(75, 192, 192)',
|
8 |
+
blue: 'rgb(54, 162, 235)',
|
9 |
+
purple: 'rgb(153, 102, 255)',
|
10 |
+
grey: 'rgb(201, 203, 207)'
|
11 |
+
};
|
12 |
+
|
13 |
+
(function(global) {
|
14 |
+
var MONTHS = [
|
15 |
+
'January',
|
16 |
+
'February',
|
17 |
+
'March',
|
18 |
+
'April',
|
19 |
+
'May',
|
20 |
+
'June',
|
21 |
+
'July',
|
22 |
+
'August',
|
23 |
+
'September',
|
24 |
+
'October',
|
25 |
+
'November',
|
26 |
+
'December'
|
27 |
+
];
|
28 |
+
|
29 |
+
var COLORS = [
|
30 |
+
'#4dc9f6',
|
31 |
+
'#f67019',
|
32 |
+
'#f53794',
|
33 |
+
'#537bc4',
|
34 |
+
'#acc236',
|
35 |
+
'#166a8f',
|
36 |
+
'#00a950',
|
37 |
+
'#58595b',
|
38 |
+
'#8549ba'
|
39 |
+
];
|
40 |
+
|
41 |
+
var Samples = global.Samples || (global.Samples = {});
|
42 |
+
var Color = global.Color;
|
43 |
+
|
44 |
+
Samples.utils = {
|
45 |
+
// Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
|
46 |
+
srand: function(seed) {
|
47 |
+
this._seed = seed;
|
48 |
+
},
|
49 |
+
|
50 |
+
rand: function(min, max) {
|
51 |
+
var seed = this._seed;
|
52 |
+
min = min === undefined ? 0 : min;
|
53 |
+
max = max === undefined ? 1 : max;
|
54 |
+
this._seed = (seed * 9301 + 49297) % 233280;
|
55 |
+
return min + (this._seed / 233280) * (max - min);
|
56 |
+
},
|
57 |
+
|
58 |
+
numbers: function(config) {
|
59 |
+
var cfg = config || {};
|
60 |
+
var min = cfg.min || 0;
|
61 |
+
var max = cfg.max || 1;
|
62 |
+
var from = cfg.from || [];
|
63 |
+
var count = cfg.count || 8;
|
64 |
+
var decimals = cfg.decimals || 8;
|
65 |
+
var continuity = cfg.continuity || 1;
|
66 |
+
var dfactor = Math.pow(10, decimals) || 0;
|
67 |
+
var data = [];
|
68 |
+
var i, value;
|
69 |
+
|
70 |
+
for (i = 0; i < count; ++i) {
|
71 |
+
value = (from[i] || 0) + this.rand(min, max);
|
72 |
+
if (this.rand() <= continuity) {
|
73 |
+
data.push(Math.round(dfactor * value) / dfactor);
|
74 |
+
} else {
|
75 |
+
data.push(null);
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
return data;
|
80 |
+
},
|
81 |
+
|
82 |
+
labels: function(config) {
|
83 |
+
var cfg = config || {};
|
84 |
+
var min = cfg.min || 0;
|
85 |
+
var max = cfg.max || 100;
|
86 |
+
var count = cfg.count || 8;
|
87 |
+
var step = (max - min) / count;
|
88 |
+
var decimals = cfg.decimals || 8;
|
89 |
+
var dfactor = Math.pow(10, decimals) || 0;
|
90 |
+
var prefix = cfg.prefix || '';
|
91 |
+
var values = [];
|
92 |
+
var i;
|
93 |
+
|
94 |
+
for (i = min; i < max; i += step) {
|
95 |
+
values.push(prefix + Math.round(dfactor * i) / dfactor);
|
96 |
+
}
|
97 |
+
|
98 |
+
return values;
|
99 |
+
},
|
100 |
+
|
101 |
+
months: function(config) {
|
102 |
+
var cfg = config || {};
|
103 |
+
var count = cfg.count || 12;
|
104 |
+
var section = cfg.section;
|
105 |
+
var values = [];
|
106 |
+
var i, value;
|
107 |
+
|
108 |
+
for (i = 0; i < count; ++i) {
|
109 |
+
value = MONTHS[Math.ceil(i) % 12];
|
110 |
+
values.push(value.substring(0, section));
|
111 |
+
}
|
112 |
+
|
113 |
+
return values;
|
114 |
+
},
|
115 |
+
|
116 |
+
color: function(index) {
|
117 |
+
return COLORS[index % COLORS.length];
|
118 |
+
},
|
119 |
+
|
120 |
+
transparentize: function(color, opacity) {
|
121 |
+
var alpha = opacity === undefined ? 0.5 : 1 - opacity;
|
122 |
+
return Color(color).alpha(alpha).rgbString();
|
123 |
+
}
|
124 |
+
};
|
125 |
+
|
126 |
+
// DEPRECATED
|
127 |
+
window.randomScalingFactor = function() {
|
128 |
+
return Math.round(Samples.utils.rand(-100, 100));
|
129 |
+
};
|
130 |
+
|
131 |
+
// INITIALIZATION
|
132 |
+
|
133 |
+
Samples.utils.srand(Date.now());
|
134 |
+
|
135 |
+
// Google Analytics
|
136 |
+
/* eslint-disable */
|
137 |
+
if (document.location.hostname.match(/^(www\.)?chartjs\.org$/)) {
|
138 |
+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
139 |
+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
140 |
+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
141 |
+
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
142 |
+
ga('create', 'UA-28909194-3', 'auto');
|
143 |
+
ga('send', 'pageview');
|
144 |
+
}
|
145 |
+
/* eslint-enable */
|
146 |
+
|
147 |
+
}(this));
|
lib/bootstrap/css/bootstrap-rtl.min.css
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@charset "UTF-8";/*!
|
2 |
+
* Bootstrap v4.4.1 (https://getbootstrap.com/)
|
3 |
+
* Copyright 2011-2019 The Bootstrap Authors
|
4 |
+
* Copyright 2011-2019 Twitter, Inc.
|
5 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
6 |
+
* RTL-ized by Arash Laylazi (https://github.com/PerseusTheGreat)
|
7 |
+
* RTL rev. 1 (https://github.com/PerseusTheGreat/bootstrap-rtl)
|
8 |
+
*/:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent;direction:rtl}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:right;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-right:0;margin-bottom:.5rem}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:right;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}[type=email],[type=file],[type=number],[type=password],[type=tel],[type=url],code,samp,var{text-align:left;direction:ltr}kbd{display:inline-block}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-right:0;list-style:none}.list-inline{padding-right:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-left:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-right:8.333333%}.offset-2{margin-right:16.666667%}.offset-3{margin-right:25%}.offset-4{margin-right:33.333333%}.offset-5{margin-right:41.666667%}.offset-6{margin-right:50%}.offset-7{margin-right:58.333333%}.offset-8{margin-right:66.666667%}.offset-9{margin-right:75%}.offset-10{margin-right:83.333333%}.offset-11{margin-right:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-right:0}.offset-sm-1{margin-right:8.333333%}.offset-sm-2{margin-right:16.666667%}.offset-sm-3{margin-right:25%}.offset-sm-4{margin-right:33.333333%}.offset-sm-5{margin-right:41.666667%}.offset-sm-6{margin-right:50%}.offset-sm-7{margin-right:58.333333%}.offset-sm-8{margin-right:66.666667%}.offset-sm-9{margin-right:75%}.offset-sm-10{margin-right:83.333333%}.offset-sm-11{margin-right:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-right:0}.offset-md-1{margin-right:8.333333%}.offset-md-2{margin-right:16.666667%}.offset-md-3{margin-right:25%}.offset-md-4{margin-right:33.333333%}.offset-md-5{margin-right:41.666667%}.offset-md-6{margin-right:50%}.offset-md-7{margin-right:58.333333%}.offset-md-8{margin-right:66.666667%}.offset-md-9{margin-right:75%}.offset-md-10{margin-right:83.333333%}.offset-md-11{margin-right:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-right:0}.offset-lg-1{margin-right:8.333333%}.offset-lg-2{margin-right:16.666667%}.offset-lg-3{margin-right:25%}.offset-lg-4{margin-right:33.333333%}.offset-lg-5{margin-right:41.666667%}.offset-lg-6{margin-right:50%}.offset-lg-7{margin-right:58.333333%}.offset-lg-8{margin-right:66.666667%}.offset-lg-9{margin-right:75%}.offset-lg-10{margin-right:83.333333%}.offset-lg-11{margin-right:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-right:0}.offset-xl-1{margin-right:8.333333%}.offset-xl-2{margin-right:16.666667%}.offset-xl-3{margin-right:25%}.offset-xl-4{margin-right:33.333333%}.offset-xl-5{margin-right:41.666667%}.offset-xl-6{margin-right:50%}.offset-xl-7{margin-right:58.333333%}.offset-xl-8{margin-right:66.666667%}.offset-xl-9{margin-right:75%}.offset-xl-10{margin-right:83.333333%}.offset-xl-11{margin-right:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-right:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-right:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-right:0;margin-left:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:0;margin-left:.3125rem}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-left:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:left calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-left:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) left calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-left:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat left .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center left 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-left:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:left calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-left:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) left calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-left:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat left .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center left 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-right:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:0;margin-left:.25rem}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-right:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:right;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-right:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-right:.255em;vertical-align:.255em;content:""}.dropright .dropdown-toggle::after{display:none}.dropright .dropdown-toggle::before{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-right:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-right:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-right:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-right-radius:0;border-bottom-right-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-right:0}.dropleft .dropdown-toggle-split::before{margin-left:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 0%;flex:1 1 0%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-right:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-right:-1px}.input-group-prepend{margin-left:-1px}.input-group-append{margin-right:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-left:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-right:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-left:1rem}.custom-control-input{position:absolute;right:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;right:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;right:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-right:2.25rem}.custom-switch .custom-control-label::before{right:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);right:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(-.75rem);transform:translateX(-.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem .375rem 1.75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat left .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-left:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-right:.5rem;padding-bottom:.25rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-right:1rem;padding-bottom:.5rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input:lang(fa)~.custom-file-label::after{content:"از فهرست"}.custom-file-input:lang(ar)~.custom-file-label::after{content:"تصفح"}.custom-file-input:lang(iw)~.custom-file-label::after{content:"דפדוף"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;bottom:0;left:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-right:inherit;border-radius:.25rem 0 0 .25rem}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-left:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-right:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-left:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-right:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-right:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-right:0;border-right:0}.card-group>.card:not(:last-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:not(:first-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-right-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-right:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-left:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-right:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-right:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item:last-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-left:4rem}.alert-dismissible .close{position:absolute;top:0;left:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-right:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal .list-group-item:first-child{border-bottom-right-radius:.25rem;border-top-left-radius:0}.list-group-horizontal .list-group-item:last-child{border-top-left-radius:.25rem;border-bottom-right-radius:0}.list-group-horizontal .list-group-item.active{margin-top:0}.list-group-horizontal .list-group-item+.list-group-item{border-top-width:1px;border-right-width:0}.list-group-horizontal .list-group-item+.list-group-item.active{margin-right:-1px;border-right-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm .list-group-item:first-child{border-bottom-right-radius:.25rem;border-top-left-radius:0}.list-group-horizontal-sm .list-group-item:last-child{border-top-left-radius:.25rem;border-bottom-right-radius:0}.list-group-horizontal-sm .list-group-item.active{margin-top:0}.list-group-horizontal-sm .list-group-item+.list-group-item{border-top-width:1px;border-right-width:0}.list-group-horizontal-sm .list-group-item+.list-group-item.active{margin-right:-1px;border-right-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md .list-group-item:first-child{border-bottom-right-radius:.25rem;border-top-left-radius:0}.list-group-horizontal-md .list-group-item:last-child{border-top-left-radius:.25rem;border-bottom-right-radius:0}.list-group-horizontal-md .list-group-item.active{margin-top:0}.list-group-horizontal-md .list-group-item+.list-group-item{border-top-width:1px;border-right-width:0}.list-group-horizontal-md .list-group-item+.list-group-item.active{margin-right:-1px;border-right-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg .list-group-item:first-child{border-bottom-right-radius:.25rem;border-top-left-radius:0}.list-group-horizontal-lg .list-group-item:last-child{border-top-left-radius:.25rem;border-bottom-right-radius:0}.list-group-horizontal-lg .list-group-item.active{margin-top:0}.list-group-horizontal-lg .list-group-item+.list-group-item{border-top-width:1px;border-right-width:0}.list-group-horizontal-lg .list-group-item+.list-group-item.active{margin-right:-1px;border-right-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl .list-group-item:first-child{border-bottom-right-radius:.25rem;border-top-left-radius:0}.list-group-horizontal-xl .list-group-item:last-child{border-top-left-radius:.25rem;border-bottom-right-radius:0}.list-group-horizontal-xl .list-group-item.active{margin-top:0}.list-group-horizontal-xl .list-group-item+.list-group-item{border-top-width:1px;border-right-width:0}.list-group-horizontal-xl .list-group-item+.list-group-item.active{margin-right:-1px;border-right-width:1px}}.list-group-flush .list-group-item{border-right-width:0;border-left-width:0;border-radius:0}.list-group-flush .list-group-item:first-child{border-top-width:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:left;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;right:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem auto -1rem -1rem}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:right;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;bord
|