Version Description
= 2.4.4.2 = * Improvements * Patched security vulnerability.
= 2.4.4.1 = * Improvements * Patched security vulnerability. * Badge UI Fix.
= 2.4.4 = New features and Bug fixes.
= 2.4.3 = Code improvement.
= 2.4.2 = Code improvement.
= 2.4.1 = New features and Bug fixes.
= 2.4 = New features and Bug fixes.
= 2.3.2 = Code improvement.
= 2.3.1 = Improve license system.
= 2.3 = New features and Bug fixes.
= 2.2 = New features and Bug fixes.
= 2.1.1 = New features and Bug fixes.
= 2.1 = New features and Bug fixes.
= 2.0 = The banking module have been replaced by Central deposite module, and interest related functionality has been removed. If you are using simple interest or compound interest related functionality, you will fine the respective functionalities missing after the update.
Release Info
Developer | wpexpertsio |
Plugin | myCRED |
Version | 2.4.4.2-beta.2 |
Comparing to | |
See all releases |
Code changes from version 2.4.4.2-beta.1 to 2.4.4.2-beta.2
- abstracts/mycred-abstract-hook.php +5 -5
- abstracts/mycred-abstract-module.php +6 -5
- addons/badges/includes/mycred-badge-functions.php +6 -6
- addons/badges/includes/mycred-badge-secondary.php +1 -1
- addons/badges/includes/mycred-badge-shortcodes.php +13 -17
- addons/badges/myCRED-addon-badges.php +16 -16
- addons/buy-creds/abstracts/mycred-abstract-payment-gateway.php +9 -9
- addons/buy-creds/gateways/netbilling.php +3 -3
- addons/cash-creds/abstracts/cashcred-abstract-payment-gateway.php +4 -4
- addons/email-notices/myCRED-addon-email-notices.php +1 -1
- addons/stats/assets/js/Chart.js +13205 -3703
- addons/stats/assets/libs/Chart.bundle.min.js +11 -8
- includes/mycred-addons-upgrader.php +0 -365
- includes/shortcodes/mycred_video.php +10 -10
@@ -113,7 +113,7 @@ if (! class_exists('myCRED_Hook') ) :
|
|
113 |
public function preferences()
|
114 |
{
|
115 |
|
116 |
-
echo '<p>' .
|
117 |
|
118 |
}
|
119 |
|
@@ -447,10 +447,10 @@ if (! class_exists('myCRED_Hook') ) :
|
|
447 |
);
|
448 |
$limits = apply_filters('mycred_hook_impose_limits', $limits, $this);
|
449 |
|
450 |
-
echo '<select name="' . $this->field_name($pref_id) . '" id="' . $this->field_id($pref_id) . '" class="form-control">';
|
451 |
|
452 |
if ($use_select ) {
|
453 |
-
echo '<option value="">' .
|
454 |
}
|
455 |
|
456 |
if (is_array($pref_id) ) {
|
@@ -467,10 +467,10 @@ if (! class_exists('myCRED_Hook') ) :
|
|
467 |
}
|
468 |
|
469 |
foreach ( $limits as $value => $description ) {
|
470 |
-
echo '<option value="' . $value . '"';
|
471 |
if ($settings == $value ) { echo ' selected="selected"';
|
472 |
}
|
473 |
-
echo '>' . $description . '</option>';
|
474 |
}
|
475 |
echo '</select>';
|
476 |
|
113 |
public function preferences()
|
114 |
{
|
115 |
|
116 |
+
echo '<p>' . esc_html__('This Hook has no settings', 'mycred') . '</p>';
|
117 |
|
118 |
}
|
119 |
|
447 |
);
|
448 |
$limits = apply_filters('mycred_hook_impose_limits', $limits, $this);
|
449 |
|
450 |
+
echo '<select name="' . esc_attr( $this->field_name($pref_id) ) . '" id="' . esc_attr( $this->field_id($pref_id) ) . '" class="form-control">';
|
451 |
|
452 |
if ($use_select ) {
|
453 |
+
echo '<option value="">' . esc_html__('Select', 'mycred') . '</option>';
|
454 |
}
|
455 |
|
456 |
if (is_array($pref_id) ) {
|
467 |
}
|
468 |
|
469 |
foreach ( $limits as $value => $description ) {
|
470 |
+
echo '<option value="' . esc_attr( $value ) . '"';
|
471 |
if ($settings == $value ) { echo ' selected="selected"';
|
472 |
}
|
473 |
+
echo '>' . esc_html( $description ) . '</option>';
|
474 |
}
|
475 |
echo '</select>';
|
476 |
|
@@ -515,10 +515,11 @@ if (! class_exists('myCRED_Module') ) :
|
|
515 |
public function set_entries_per_page()
|
516 |
{
|
517 |
|
518 |
-
if (! isset($_REQUEST['wp_screen_options']['option']) || ! isset($_REQUEST['wp_screen_options']['value']) ) {
|
|
|
519 |
}
|
520 |
|
521 |
-
$settings_key = 'mycred_epp_' . $_GET['page'];
|
522 |
|
523 |
if ($_REQUEST['wp_screen_options']['option'] == $settings_key ) {
|
524 |
$value = absint($_REQUEST['wp_screen_options']['value']);
|
@@ -593,8 +594,8 @@ if (! class_exists('myCRED_Module') ) :
|
|
593 |
<!-- myCRED Accordion Styling -->
|
594 |
<style type="text/css">
|
595 |
h4:before { float:right; padding-right: 12px; font-size: 14px; font-weight: normal; color: silver; }
|
596 |
-
h4.ui-accordion-header.ui-state-active:before { content: "<?php
|
597 |
-
h4.ui-accordion-header:before { content: "<?php
|
598 |
</style>
|
599 |
<?php
|
600 |
|
@@ -639,7 +640,7 @@ h4.ui-accordion-header:before { content: "<?php _e('click to open', 'mycred'); ?
|
|
639 |
}
|
640 |
|
641 |
if (isset($_GET[ $get ]) ) {
|
642 |
-
echo '<div class="' . $class . '"><p>' . $message . '</p></div>';
|
643 |
}
|
644 |
|
645 |
}
|
515 |
public function set_entries_per_page()
|
516 |
{
|
517 |
|
518 |
+
if (! isset($_REQUEST['wp_screen_options']['option']) || ! isset($_REQUEST['wp_screen_options']['value']) || ! isset( $_GET['page'] ) ) {
|
519 |
+
return;
|
520 |
}
|
521 |
|
522 |
+
$settings_key = 'mycred_epp_' . sanitize_key( $_GET['page'] );
|
523 |
|
524 |
if ($_REQUEST['wp_screen_options']['option'] == $settings_key ) {
|
525 |
$value = absint($_REQUEST['wp_screen_options']['value']);
|
594 |
<!-- myCRED Accordion Styling -->
|
595 |
<style type="text/css">
|
596 |
h4:before { float:right; padding-right: 12px; font-size: 14px; font-weight: normal; color: silver; }
|
597 |
+
h4.ui-accordion-header.ui-state-active:before { content: "<?php esc_html_e('click to close', 'mycred'); ?>"; }
|
598 |
+
h4.ui-accordion-header:before { content: "<?php esc_html_e('click to open', 'mycred'); ?>"; }
|
599 |
</style>
|
600 |
<?php
|
601 |
|
640 |
}
|
641 |
|
642 |
if (isset($_GET[ $get ]) ) {
|
643 |
+
echo '<div class="' . esc_attr( $class ) . '"><p>' . esc_html( $message ) . '</p></div>';
|
644 |
}
|
645 |
|
646 |
}
|
@@ -317,9 +317,9 @@ if (! function_exists('mycred_display_badge_requirement') ) :
|
|
317 |
}
|
318 |
|
319 |
if ($requirement['by'] == 'count' ) {
|
320 |
-
$rendered_row = sprintf(
|
321 |
} else {
|
322 |
-
$rendered_row = sprintf(
|
323 |
}
|
324 |
|
325 |
$compare = _x('OR', 'Comparison of badge requirements. A OR B', 'mycred');
|
@@ -343,7 +343,7 @@ if (! function_exists('mycred_display_badge_requirement') ) :
|
|
343 |
}
|
344 |
|
345 |
if ((int) mycred_get_post_meta($badge_id, 'manual_badge', true) === 1 ) {
|
346 |
-
$output[] = '<strong><small><em>' .
|
347 |
}
|
348 |
|
349 |
$reply = implode('', $output);
|
@@ -750,7 +750,7 @@ if (! function_exists('mycred_display_users_badges') ) :
|
|
750 |
}
|
751 |
|
752 |
if (!empty($badge_image) ) {
|
753 |
-
echo apply_filters('mycred_the_badge', $badge_image, $badge_id, $badge, $user_id);
|
754 |
}
|
755 |
|
756 |
}
|
@@ -919,9 +919,9 @@ if(!function_exists('mycred_show_badge_requirements') ) :
|
|
919 |
}
|
920 |
|
921 |
if ($requirement['by'] == 'count') {
|
922 |
-
$rendered_row = sprintf(
|
923 |
} else {
|
924 |
-
$rendered_row = sprintf(
|
925 |
}
|
926 |
|
927 |
$compare = _x('OR', 'Comparison of badge requirements. A OR B', 'mycred');
|
317 |
}
|
318 |
|
319 |
if ($requirement['by'] == 'count' ) {
|
320 |
+
$rendered_row = sprintf(esc_html_x('%s for "%s" x %d', '"Points" for "reference" x times', 'mycred'), $mycred->plural(), $requirement['ref'], $requirement['amount']);
|
321 |
} else {
|
322 |
+
$rendered_row = sprintf(esc_html_x('%s %s for "%s"', '"Gained/Lost" "x points" for "reference"', 'mycred'), ( ( $requirement['amount'] < 0 ) ? esc_html__('Lost', 'mycred') : esc_html__('Gained', 'mycred') ), $mycred->format_creds($requirement['amount']), $requirement['ref']);
|
323 |
}
|
324 |
|
325 |
$compare = _x('OR', 'Comparison of badge requirements. A OR B', 'mycred');
|
343 |
}
|
344 |
|
345 |
if ((int) mycred_get_post_meta($badge_id, 'manual_badge', true) === 1 ) {
|
346 |
+
$output[] = '<strong><small><em>' . esc_html__('This badge is manually awarded.', 'mycred') . '</em></small></strong>';
|
347 |
}
|
348 |
|
349 |
$reply = implode('', $output);
|
750 |
}
|
751 |
|
752 |
if (!empty($badge_image) ) {
|
753 |
+
echo apply_filters('mycred_the_badge', wp_kses_post( $badge_image ), $badge_id, $badge, $user_id);
|
754 |
}
|
755 |
|
756 |
}
|
919 |
}
|
920 |
|
921 |
if ($requirement['by'] == 'count') {
|
922 |
+
$rendered_row = sprintf(esc_html_x('%s for "%s" x %d', '"Points" for "reference" x times', 'mycred'), $mycred->plural(), $requirement['ref'], $requirement['amount']);
|
923 |
} else {
|
924 |
+
$rendered_row = sprintf(esc_html_x('%s %s for "%s"', '"Gained/Lost" "x points" for "reference"', 'mycred'), (($requirement['amount'] < 0) ? __('Lost', 'mycred') : __('Gained', 'mycred')), $mycred->format_creds($requirement['amount']), $requirement['ref']);
|
925 |
}
|
926 |
|
927 |
$compare = _x('OR', 'Comparison of badge requirements. A OR B', 'mycred');
|
@@ -95,7 +95,7 @@ if (! class_exists('myCRED_Badge_Secondary') ) :
|
|
95 |
$form_list .= '<option value="'.$form->id.'">'. htmlentities($form->title, ENT_QUOTES) .'</option>';
|
96 |
}
|
97 |
$data = '<div class="form-group"><select name="{{element_name}}" class="form-control specific" data-row="{{reqlevel}}" >'.$form_list.'</select></div>';
|
98 |
-
echo "var mycred_badge_gravity_form_submission = '"
|
99 |
}
|
100 |
?>
|
101 |
</script>
|
95 |
$form_list .= '<option value="'.$form->id.'">'. htmlentities($form->title, ENT_QUOTES) .'</option>';
|
96 |
}
|
97 |
$data = '<div class="form-group"><select name="{{element_name}}" class="form-control specific" data-row="{{reqlevel}}" >'.$form_list.'</select></div>';
|
98 |
+
echo "var mycred_badge_gravity_form_submission = '".wp_kses_post($data)."';";
|
99 |
}
|
100 |
?>
|
101 |
</script>
|
@@ -71,28 +71,24 @@ if (! function_exists('mycred_render_my_badges') ) :
|
|
71 |
|
72 |
if ($badge->main_image !== false ) {
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
echo '<div class="demo-badge-image">' . $badge_img . '</div>';
|
77 |
|
78 |
if($title == 'show') {
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
echo '<div class="demo-badge-title">' . $badge_title . ' '.'</div>';
|
83 |
|
84 |
} else {
|
85 |
|
86 |
-
echo
|
87 |
|
88 |
}
|
89 |
|
90 |
if($post_excerpt == 'show') {
|
91 |
|
92 |
-
echo
|
93 |
|
94 |
} else {
|
95 |
-
echo
|
96 |
}
|
97 |
|
98 |
}
|
@@ -114,26 +110,26 @@ if (! function_exists('mycred_render_my_badges') ) :
|
|
114 |
if ($badge->level_image !== false ) {
|
115 |
|
116 |
|
117 |
-
echo '<div class="demo-badge-image">' . $badge->get_image($level) . '</div>';
|
118 |
|
119 |
if($title == 'show') {
|
120 |
|
121 |
-
echo '<div class="demo-badge-title">' . $badge->title . ' '.'</div>';
|
122 |
|
123 |
}
|
124 |
|
125 |
else {
|
126 |
|
127 |
-
echo '<div class="demo-badge-title" style="display:none;">' . $badge->title . ' '.'</div>';
|
128 |
|
129 |
}
|
130 |
|
131 |
if($post_excerpt == 'show') {
|
132 |
|
133 |
-
echo '<div class="page-excerpt">' . $badge_page_id->post_excerpt . ' '.'</div>';
|
134 |
|
135 |
} else {
|
136 |
-
echo '<div class="page-excerpt" style="display:none;">' . $badge_page_id->post_excerpt . ' '.'</div>';;
|
137 |
}
|
138 |
|
139 |
}
|
@@ -269,7 +265,7 @@ if(!function_exists('mycred_render_badges_list') ) :
|
|
269 |
<?php
|
270 |
foreach ( $badges['tabs'] as $id => $element ) {
|
271 |
|
272 |
-
echo $element;
|
273 |
|
274 |
}
|
275 |
?>
|
@@ -279,7 +275,7 @@ if(!function_exists('mycred_render_badges_list') ) :
|
|
279 |
<?php
|
280 |
foreach ( $badges['panels'] as $id => $element ) {
|
281 |
|
282 |
-
echo $element;
|
283 |
|
284 |
}
|
285 |
?>
|
@@ -291,7 +287,7 @@ if(!function_exists('mycred_render_badges_list') ) :
|
|
291 |
else {
|
292 |
|
293 |
echo '<div class="mycred-badges-list-all">';
|
294 |
-
echo mycred_get_uncategorized_badge_list();
|
295 |
echo '</div>';
|
296 |
|
297 |
}
|
71 |
|
72 |
if ($badge->main_image !== false ) {
|
73 |
|
74 |
+
echo '<div class="demo-badge-image">' . wp_kses_post( $badge_img ) . '</div>';
|
|
|
|
|
75 |
|
76 |
if($title == 'show') {
|
77 |
|
78 |
+
echo '<div class="demo-badge-title">' . esc_html( $badge_title ) . ' '.'</div>';
|
|
|
|
|
79 |
|
80 |
} else {
|
81 |
|
82 |
+
echo '<div class="demo-badge-title" style="display:none;">' . esc_html( $badge_title ) . ' '.'</div>';
|
83 |
|
84 |
}
|
85 |
|
86 |
if($post_excerpt == 'show') {
|
87 |
|
88 |
+
echo '<div class="page-excerpt">' . wp_kses_post( $page_id->post_excerpt ) . ' '.'</div>';
|
89 |
|
90 |
} else {
|
91 |
+
echo '<div class="page-excerpt" style="display:none;">' . wp_kses_post( $page_id->post_excerpt ) . ' '.'</div>';
|
92 |
}
|
93 |
|
94 |
}
|
110 |
if ($badge->level_image !== false ) {
|
111 |
|
112 |
|
113 |
+
echo '<div class="demo-badge-image">' . wp_kses_post( $badge->get_image($level) ) . '</div>';
|
114 |
|
115 |
if($title == 'show') {
|
116 |
|
117 |
+
echo '<div class="demo-badge-title">' . esc_html( $badge->title ) . ' '.'</div>';
|
118 |
|
119 |
}
|
120 |
|
121 |
else {
|
122 |
|
123 |
+
echo '<div class="demo-badge-title" style="display:none;">' . esc_html( $badge->title ) . ' '.'</div>';
|
124 |
|
125 |
}
|
126 |
|
127 |
if($post_excerpt == 'show') {
|
128 |
|
129 |
+
echo '<div class="page-excerpt">' . wp_kses_post( $badge_page_id->post_excerpt ) . ' '.'</div>';
|
130 |
|
131 |
} else {
|
132 |
+
echo '<div class="page-excerpt" style="display:none;">' . wp_kses_post( $badge_page_id->post_excerpt ) . ' '.'</div>';;
|
133 |
}
|
134 |
|
135 |
}
|
265 |
<?php
|
266 |
foreach ( $badges['tabs'] as $id => $element ) {
|
267 |
|
268 |
+
echo wp_kses_post( $element );
|
269 |
|
270 |
}
|
271 |
?>
|
275 |
<?php
|
276 |
foreach ( $badges['panels'] as $id => $element ) {
|
277 |
|
278 |
+
echo wp_kses_post( $element );
|
279 |
|
280 |
}
|
281 |
?>
|
287 |
else {
|
288 |
|
289 |
echo '<div class="mycred-badges-list-all">';
|
290 |
+
echo wp_kses_post( mycred_get_uncategorized_badge_list() );
|
291 |
echo '</div>';
|
292 |
|
293 |
}
|
@@ -502,7 +502,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
|
|
502 |
|
503 |
}
|
504 |
|
505 |
-
elseif ( $pagenow == 'post.php' && isset( $_GET['post'] ) && mycred_get_post_type( $_GET['post'] ) == MYCRED_BADGE_KEY ) {
|
506 |
|
507 |
return MYCRED_MAIN_SLUG;
|
508 |
|
@@ -534,7 +534,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
|
|
534 |
|
535 |
}
|
536 |
|
537 |
-
elseif ( $pagenow == 'post.php' && isset( $_GET['post'] ) && mycred_get_post_type( $_GET['post'] ) == MYCRED_BADGE_KEY ) {
|
538 |
|
539 |
return 'edit.php?post_type=' . MYCRED_BADGE_KEY;
|
540 |
|
@@ -624,7 +624,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
|
|
624 |
echo '-';
|
625 |
|
626 |
elseif ( $badge->main_image !== false )
|
627 |
-
echo $badge->main_image;
|
628 |
|
629 |
}
|
630 |
|
@@ -636,14 +636,14 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
|
|
636 |
if ( $badge->open_badge || $image === false )
|
637 |
echo '-';
|
638 |
else
|
639 |
-
echo $image;
|
640 |
|
641 |
}
|
642 |
|
643 |
// Badge Requirements
|
644 |
elseif ( $column_name == 'badge-reqs' ) {
|
645 |
|
646 |
-
echo mycred_display_badge_requirements( $badge_id );
|
647 |
|
648 |
}
|
649 |
|
@@ -655,7 +655,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
|
|
655 |
echo 0;
|
656 |
|
657 |
else
|
658 |
-
echo $badge->earnedby;
|
659 |
|
660 |
}
|
661 |
|
@@ -664,7 +664,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
|
|
664 |
|
665 |
$badge = mycred_get_badge_type( $badge_id );
|
666 |
|
667 |
-
echo $badge == false ? 'No Acheivement Type' : $badge;
|
668 |
|
669 |
}
|
670 |
|
@@ -929,9 +929,9 @@ th#badge-users { width: 10%; }
|
|
929 |
|
930 |
<?php do_action( 'mycred_edit_badge_before_actions', $post ); ?>
|
931 |
|
932 |
-
<input type="hidden" name="mycred-badge-edit" value="<?php echo wp_create_nonce( 'edit-mycred-badge' ); ?>" />
|
933 |
-
<input type="button" id="mycred-assign-badge-connections"<?php if ( $manual_badge || $post->post_status != 'publish' ) echo ' disabled="disabled"'; ?> value="<?php
|
934 |
-
<input type="button" id="mycred-remove-badge-connections"<?php if ( $post->post_status != 'publish' ) echo ' disabled="disabled"'; ?> value="<?php
|
935 |
|
936 |
<?php do_action( 'mycred_edit_badge_after_actions', $post ); ?>
|
937 |
|
@@ -947,7 +947,7 @@ th#badge-users { width: 10%; }
|
|
947 |
data : {
|
948 |
action : button.attr( 'data-action' ),
|
949 |
token : button.attr( 'data-token' ),
|
950 |
-
badge_id : <?php echo $post->ID; ?>
|
951 |
},
|
952 |
dataType : "JSON",
|
953 |
url : ajaxurl,
|
@@ -970,7 +970,7 @@ th#badge-users { width: 10%; }
|
|
970 |
|
971 |
</div>
|
972 |
<div id="mycred-manual-badge" class="seperate-bottom">
|
973 |
-
<label for="mycred-badge-is-manual"><input type="checkbox" name="mycred_badge[manual]" id="mycred-badge-is-manual"<?php
|
974 |
</div>
|
975 |
<?php
|
976 |
|
@@ -998,16 +998,16 @@ th#badge-users { width: 10%; }
|
|
998 |
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
999 |
<div class="default-image text-center seperate-bottom">
|
1000 |
<div class="default-image-wrapper image-wrapper<?php if ( $default_image == '' ) echo ' empty dashicons'; ?>">
|
1001 |
-
<?php echo $default_image; ?>
|
1002 |
<input type="hidden" name="mycred_badge[main_image]" id="badge-main-image-id" value="<?php if ( $attachment ) echo esc_attr( $di ); ?>" />
|
1003 |
<input type="hidden" name="mycred_badge[main_image_url]" id="badge-main-image-url" value="<?php if ( $di != '' && strpos( '://', $di ) !== false ) echo esc_attr( $default_image ); ?>" />
|
1004 |
</div>
|
1005 |
<div class="level-image-actions">
|
1006 |
-
<button type="button" class="button button-secondary" id="badges-change-default-image" data-do="<?php if ( $default_image == '' ) echo 'set'; else echo 'change'; ?>"><?php if ( $default_image == '' )
|
1007 |
-
<button type="button" class="button button-secondary <?php echo ( ( ! $attachment ) ? 'hidden' : '' ); ?>" id="badges-remove-default-image"><?php
|
1008 |
</div>
|
1009 |
</div>
|
1010 |
-
<span class="description"><?php
|
1011 |
</div>
|
1012 |
</div>
|
1013 |
<?php
|
502 |
|
503 |
}
|
504 |
|
505 |
+
elseif ( $pagenow == 'post.php' && isset( $_GET['post'] ) && mycred_get_post_type( sanitize_key( $_GET['post'] ) ) == MYCRED_BADGE_KEY ) {
|
506 |
|
507 |
return MYCRED_MAIN_SLUG;
|
508 |
|
534 |
|
535 |
}
|
536 |
|
537 |
+
elseif ( $pagenow == 'post.php' && isset( $_GET['post'] ) && mycred_get_post_type( sanitize_key( $_GET['post'] ) ) == MYCRED_BADGE_KEY ) {
|
538 |
|
539 |
return 'edit.php?post_type=' . MYCRED_BADGE_KEY;
|
540 |
|
624 |
echo '-';
|
625 |
|
626 |
elseif ( $badge->main_image !== false )
|
627 |
+
echo wp_kses_post($badge->main_image);
|
628 |
|
629 |
}
|
630 |
|
636 |
if ( $badge->open_badge || $image === false )
|
637 |
echo '-';
|
638 |
else
|
639 |
+
echo wp_kses_post($image);
|
640 |
|
641 |
}
|
642 |
|
643 |
// Badge Requirements
|
644 |
elseif ( $column_name == 'badge-reqs' ) {
|
645 |
|
646 |
+
echo wp_kses_post( mycred_display_badge_requirements( $badge_id ) );
|
647 |
|
648 |
}
|
649 |
|
655 |
echo 0;
|
656 |
|
657 |
else
|
658 |
+
echo esc_html( $badge->earnedby );
|
659 |
|
660 |
}
|
661 |
|
664 |
|
665 |
$badge = mycred_get_badge_type( $badge_id );
|
666 |
|
667 |
+
echo esc_html( $badge == false ? 'No Acheivement Type' : $badge );
|
668 |
|
669 |
}
|
670 |
|
929 |
|
930 |
<?php do_action( 'mycred_edit_badge_before_actions', $post ); ?>
|
931 |
|
932 |
+
<input type="hidden" name="mycred-badge-edit" value="<?php echo esc_attr( wp_create_nonce( 'edit-mycred-badge' ) ); ?>" />
|
933 |
+
<input type="button" id="mycred-assign-badge-connections"<?php if ( $manual_badge || $post->post_status != 'publish' ) echo ' disabled="disabled"'; ?> value="<?php esc_attr_e( 'Assign Badge', 'mycred' ); ?>" class="button button-secondary mycred-badge-action-button" data-action="mycred-assign-badge" data-token="<?php echo esc_attr( wp_create_nonce( 'mycred-assign-badge' ) ); ?>" />
|
934 |
+
<input type="button" id="mycred-remove-badge-connections"<?php if ( $post->post_status != 'publish' ) echo ' disabled="disabled"'; ?> value="<?php esc_attr_e( 'Remove Connections', 'mycred' ); ?>" class="button button-secondary mycred-badge-action-button" data-action="mycred-remove-connections" data-token="<?php echo esc_attr( wp_create_nonce( 'mycred-remove-badge-connection' ) ); ?>" />
|
935 |
|
936 |
<?php do_action( 'mycred_edit_badge_after_actions', $post ); ?>
|
937 |
|
947 |
data : {
|
948 |
action : button.attr( 'data-action' ),
|
949 |
token : button.attr( 'data-token' ),
|
950 |
+
badge_id : <?php echo esc_js( $post->ID ); ?>
|
951 |
},
|
952 |
dataType : "JSON",
|
953 |
url : ajaxurl,
|
970 |
|
971 |
</div>
|
972 |
<div id="mycred-manual-badge" class="seperate-bottom">
|
973 |
+
<label for="mycred-badge-is-manual"><input type="checkbox" name="mycred_badge[manual]" id="mycred-badge-is-manual" <?php checked( $manual_badge );?> value="1" /> <?php esc_html_e( 'This badge is manually awarded.', 'mycred' ); ?></label>
|
974 |
</div>
|
975 |
<?php
|
976 |
|
998 |
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
999 |
<div class="default-image text-center seperate-bottom">
|
1000 |
<div class="default-image-wrapper image-wrapper<?php if ( $default_image == '' ) echo ' empty dashicons'; ?>">
|
1001 |
+
<?php echo wp_kses_post($default_image); ?>
|
1002 |
<input type="hidden" name="mycred_badge[main_image]" id="badge-main-image-id" value="<?php if ( $attachment ) echo esc_attr( $di ); ?>" />
|
1003 |
<input type="hidden" name="mycred_badge[main_image_url]" id="badge-main-image-url" value="<?php if ( $di != '' && strpos( '://', $di ) !== false ) echo esc_attr( $default_image ); ?>" />
|
1004 |
</div>
|
1005 |
<div class="level-image-actions">
|
1006 |
+
<button type="button" class="button button-secondary" id="badges-change-default-image" data-do="<?php if ( $default_image == '' ) echo 'set'; else echo 'change'; ?>"><?php if ( $default_image == '' ) esc_html_e( 'Set Image', 'mycred' ); else esc_html_e( 'Change Image', 'mycred' ); ?></button>
|
1007 |
+
<button type="button" class="button button-secondary <?php echo ( ( ! $attachment ) ? 'hidden' : '' ); ?>" id="badges-remove-default-image"><?php esc_html_e( 'Remove Image', 'mycred' ); ?></button>
|
1008 |
</div>
|
1009 |
</div>
|
1010 |
+
<span class="description"><?php esc_html_e( 'Optional image to show when a user has not earned this badge.', 'mycred' ); ?></span>
|
1011 |
</div>
|
1012 |
</div>
|
1013 |
<?php
|
@@ -2252,11 +2252,11 @@ if (! class_exists('myCRED_Payment_Gateway') ) :
|
|
2252 |
{
|
2253 |
|
2254 |
if ($method == 'POST' ) {
|
2255 |
-
$post_id = $_POST[ $sales_data_key ];
|
2256 |
} elseif ($method == 'GET' ) {
|
2257 |
-
$post_id = $_GET[ $sales_data_key ];
|
2258 |
} else {
|
2259 |
-
$post_id = $_REQUEST[ $sales_data_key ];
|
2260 |
}
|
2261 |
|
2262 |
$pending_payment = $this->get_pending_payment($post_id);
|
@@ -2266,11 +2266,11 @@ if (! class_exists('myCRED_Payment_Gateway') ) :
|
|
2266 |
$result = true;
|
2267 |
|
2268 |
if ($method == 'POST' ) {
|
2269 |
-
$price = $_POST[ $cost_key ];
|
2270 |
} elseif ($method == 'GET' ) {
|
2271 |
-
$price = $_GET[ $cost_key ];
|
2272 |
} else {
|
2273 |
-
$price = $_REQUEST[ $cost_key ];
|
2274 |
}
|
2275 |
|
2276 |
if ($result === true && $pending_payment['cost'] != $price ) {
|
@@ -2282,11 +2282,11 @@ if (! class_exists('myCRED_Payment_Gateway') ) :
|
|
2282 |
}
|
2283 |
|
2284 |
if ($method == 'POST' ) {
|
2285 |
-
$transaction_id = $_POST[ $transactionid_key ];
|
2286 |
} elseif ($method == 'GET' ) {
|
2287 |
-
$transaction_id = $_GET[ $transactionid_key ];
|
2288 |
} else {
|
2289 |
-
$transaction_id = $_REQUEST[ $transactionid_key ];
|
2290 |
}
|
2291 |
|
2292 |
if ($result === true && ! $this->transaction_id_is_unique($transaction_id) ) {
|
2252 |
{
|
2253 |
|
2254 |
if ($method == 'POST' ) {
|
2255 |
+
$post_id = absint( $_POST[ $sales_data_key ] );
|
2256 |
} elseif ($method == 'GET' ) {
|
2257 |
+
$post_id = absint( $_GET[ $sales_data_key ] );
|
2258 |
} else {
|
2259 |
+
$post_id = absint( $_REQUEST[ $sales_data_key ] );
|
2260 |
}
|
2261 |
|
2262 |
$pending_payment = $this->get_pending_payment($post_id);
|
2266 |
$result = true;
|
2267 |
|
2268 |
if ($method == 'POST' ) {
|
2269 |
+
$price = floatval( $_POST[ $cost_key ] );
|
2270 |
} elseif ($method == 'GET' ) {
|
2271 |
+
$price = floatval( $_GET[ $cost_key ] );
|
2272 |
} else {
|
2273 |
+
$price = floatval( $_REQUEST[ $cost_key ] );
|
2274 |
}
|
2275 |
|
2276 |
if ($result === true && $pending_payment['cost'] != $price ) {
|
2282 |
}
|
2283 |
|
2284 |
if ($method == 'POST' ) {
|
2285 |
+
$transaction_id = sanitize_title( $_POST[ $transactionid_key ] );
|
2286 |
} elseif ($method == 'GET' ) {
|
2287 |
+
$transaction_id = sanitize_title( $_GET[ $transactionid_key ] );
|
2288 |
} else {
|
2289 |
+
$transaction_id = sanitize_title( $_REQUEST[ $transactionid_key ] );
|
2290 |
}
|
2291 |
|
2292 |
if ($result === true && ! $this->transaction_id_is_unique($transaction_id) ) {
|
@@ -103,13 +103,13 @@ if (! class_exists('myCRED_NETbilling') ) :
|
|
103 |
|
104 |
// Check amount paid
|
105 |
if ($_REQUEST['Ecom_Cost_Total'] != $pending_payment->cost ) {
|
106 |
-
$new_call[] = sprintf(__('Price mismatch. Expected: %s Received: %s', 'mycred'), $pending_payment->cost, $_REQUEST['Ecom_Cost_Total']);
|
107 |
$errors = true;
|
108 |
}
|
109 |
|
110 |
// Check status
|
111 |
if ($_REQUEST['Ecom_Ezic_Response_StatusCode'] != 1 ) {
|
112 |
-
$new_call[] = sprintf(__('Payment not completed. Received: %s', 'mycred'), $_REQUEST['Ecom_Ezic_Response_StatusCode']);
|
113 |
$errors = true;
|
114 |
}
|
115 |
|
@@ -117,7 +117,7 @@ if (! class_exists('myCRED_NETbilling') ) :
|
|
117 |
if ($errors === false ) {
|
118 |
|
119 |
// If account is credited, delete the post and it's comments.
|
120 |
-
if ($this->complete_payment($pending_payment, $_REQUEST['Ecom_Ezic_Response_TransactionID']) ) {
|
121 |
$this->trash_pending_payment($pending_post_id);
|
122 |
} else {
|
123 |
$new_call[] = __('Failed to credit users account.', 'mycred');
|
103 |
|
104 |
// Check amount paid
|
105 |
if ($_REQUEST['Ecom_Cost_Total'] != $pending_payment->cost ) {
|
106 |
+
$new_call[] = sprintf(__('Price mismatch. Expected: %s Received: %s', 'mycred'), $pending_payment->cost, floatval( $_REQUEST['Ecom_Cost_Total'] ));
|
107 |
$errors = true;
|
108 |
}
|
109 |
|
110 |
// Check status
|
111 |
if ($_REQUEST['Ecom_Ezic_Response_StatusCode'] != 1 ) {
|
112 |
+
$new_call[] = sprintf(__('Payment not completed. Received: %s', 'mycred'), intval( $_REQUEST['Ecom_Ezic_Response_StatusCode'] ));
|
113 |
$errors = true;
|
114 |
}
|
115 |
|
117 |
if ($errors === false ) {
|
118 |
|
119 |
// If account is credited, delete the post and it's comments.
|
120 |
+
if ($this->complete_payment($pending_payment, sanitize_title( $_REQUEST['Ecom_Ezic_Response_TransactionID'] )) ) {
|
121 |
$this->trash_pending_payment($pending_post_id);
|
122 |
} else {
|
123 |
$new_call[] = __('Failed to credit users account.', 'mycred');
|
@@ -727,10 +727,10 @@ if (! class_exists('myCRED_Cash_Payment_Gateway') ) :
|
|
727 |
);
|
728 |
|
729 |
foreach ( $months as $number => $text ) {
|
730 |
-
echo '<option value="' . $number . '"';
|
731 |
if ($selected == $number ) { echo ' selected="selected"';
|
732 |
}
|
733 |
-
echo '>' . $text . '</option>';
|
734 |
}
|
735 |
|
736 |
}
|
@@ -760,10 +760,10 @@ if (! class_exists('myCRED_Cash_Payment_Gateway') ) :
|
|
760 |
}
|
761 |
|
762 |
foreach ( $options as $key => $value ) {
|
763 |
-
echo '<option value="' . $key . '"';
|
764 |
if ($selected == $key ) { echo ' selected="selected"';
|
765 |
}
|
766 |
-
echo '>' . $value . '</option>';
|
767 |
}
|
768 |
|
769 |
}
|
727 |
);
|
728 |
|
729 |
foreach ( $months as $number => $text ) {
|
730 |
+
echo '<option value="' . esc_attr( $number ) . '"';
|
731 |
if ($selected == $number ) { echo ' selected="selected"';
|
732 |
}
|
733 |
+
echo '>' . esc_html( $text ) . '</option>';
|
734 |
}
|
735 |
|
736 |
}
|
760 |
}
|
761 |
|
762 |
foreach ( $options as $key => $value ) {
|
763 |
+
echo '<option value="' . esc_attr( $key ) . '"';
|
764 |
if ($selected == $key ) { echo ' selected="selected"';
|
765 |
}
|
766 |
+
echo '>' . esc_html( $value ) . '</option>';
|
767 |
}
|
768 |
|
769 |
}
|
@@ -940,7 +940,7 @@ if ( ! class_exists( 'myCRED_Email_Notice_Module' ) ) :
|
|
940 |
else {
|
941 |
|
942 |
$reference_list = array();
|
943 |
-
$custom_reference = explode( ',', $_POST['mycred_email']['custom_reference'] );
|
944 |
|
945 |
foreach ( $custom_reference as $reference_id ) {
|
946 |
|
940 |
else {
|
941 |
|
942 |
$reference_list = array();
|
943 |
+
$custom_reference = explode( ',', sanitize_text_field( $_POST['mycred_email']['custom_reference'] ) );
|
944 |
|
945 |
foreach ( $custom_reference as $reference_id ) {
|
946 |
|
@@ -1,3767 +1,13269 @@
|
|
1 |
-
|
2 |
-
* Chart.js
|
3 |
-
*
|
4 |
-
*
|
|
|
5 |
*/
|
6 |
-
(function () {
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
this.ctx = context;
|
20 |
-
|
21 |
-
//Variables global to the chart
|
22 |
-
var width = this.width = context.canvas.width;
|
23 |
-
var height = this.height = context.canvas.height;
|
24 |
-
this.aspectRatio = this.width / this.height;
|
25 |
-
//High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
|
26 |
-
helpers.retinaScale(this);
|
27 |
-
|
28 |
-
return this;
|
29 |
};
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
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 |
};
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
}
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
);
|
196 |
-
|
197 |
-
}
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
208 |
-
);
|
209 |
-
return base;
|
210 |
-
},
|
211 |
-
merge = helpers.merge = function (base,master) {
|
212 |
-
//Merge properties in left object over to a shallow clone of object right.
|
213 |
-
var args = Array.prototype.slice.call(arguments,0);
|
214 |
-
args.unshift({});
|
215 |
-
return extend.apply(null, args);
|
216 |
-
},
|
217 |
-
indexOf = helpers.indexOf = function (arrayToSearch, item) {
|
218 |
-
if (Array.prototype.indexOf) {
|
219 |
-
return arrayToSearch.indexOf(item);
|
220 |
}
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
}
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
if (filterCallback(item)) {
|
235 |
-
filtered.push(item);
|
236 |
-
}
|
237 |
-
}
|
238 |
-
);
|
239 |
-
|
240 |
-
return filtered;
|
241 |
-
},
|
242 |
-
findNextWhere = helpers.findNextWhere = function (arrayToSearch, filterCallback, startIndex) {
|
243 |
-
// Default to start of the array
|
244 |
-
if (!startIndex) {
|
245 |
-
startIndex = -1;
|
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 |
-
else {
|
327 |
-
return 0;
|
328 |
-
}
|
329 |
},
|
330 |
-
|
331 |
-
|
332 |
},
|
333 |
-
|
334 |
-
|
335 |
-
var distanceFromXCenter = anglePoint.x - centrePoint.x,
|
336 |
-
distanceFromYCenter = anglePoint.y - centrePoint.y,
|
337 |
-
radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
|
338 |
-
|
339 |
-
|
340 |
-
var angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);
|
341 |
-
|
342 |
-
//If the segment is in the top left quadrant, we need to add another rotation to the angle
|
343 |
-
if (distanceFromXCenter < 0 && distanceFromYCenter < 0) {
|
344 |
-
angle += Math.PI*2;
|
345 |
-
}
|
346 |
-
|
347 |
-
return {
|
348 |
-
angle: angle,
|
349 |
-
distance: radialDistanceFromCenter
|
350 |
-
};
|
351 |
},
|
352 |
-
|
353 |
-
|
354 |
},
|
355 |
-
|
356 |
-
|
357 |
-
//http://scaledinnovation.com/analytics/splines/aboutSplines.html
|
358 |
-
var d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),
|
359 |
-
d12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),
|
360 |
-
fa=t*d01/(d01+d12),// scaling factor for triangle Ta
|
361 |
-
fb=t*d12/(d01+d12);
|
362 |
-
return {
|
363 |
-
inner : {
|
364 |
-
x : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),
|
365 |
-
y : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)
|
366 |
-
},
|
367 |
-
outer : {
|
368 |
-
x: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),
|
369 |
-
y : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)
|
370 |
-
}
|
371 |
-
};
|
372 |
},
|
373 |
-
|
374 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
},
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
var minSteps = 2,
|
380 |
-
maxSteps = Math.floor(drawingSize/(textSize * 1.5)),
|
381 |
-
skipFitting = (minSteps >= maxSteps);
|
382 |
-
|
383 |
-
var maxValue = max(valuesArray),
|
384 |
-
minValue = Number.POSITIVE_INFINITY;
|
385 |
-
|
386 |
-
// Ignore nulls since we don't construct points for them (since Math.min treats them as 0)
|
387 |
-
each(
|
388 |
-
valuesArray, function ( value ) {
|
389 |
-
if (value < minValue && value != null) {
|
390 |
-
minValue = value;
|
391 |
-
}
|
392 |
-
}
|
393 |
-
);
|
394 |
-
|
395 |
-
// We need some degree of seperation here to calculate the scales if all the values are the same
|
396 |
-
// Adding/minusing 0.5 will give us a range of 1.
|
397 |
-
if (maxValue === minValue) {
|
398 |
-
maxValue += 0.5;
|
399 |
-
// So we don't end up with a graph with a negative start value if we've said always start from zero
|
400 |
-
if (minValue >= 0.5 && !startFromZero) {
|
401 |
-
minValue -= 0.5;
|
402 |
-
}
|
403 |
-
else{
|
404 |
-
// Make up a whole number above the values
|
405 |
-
maxValue += 0.5;
|
406 |
-
}
|
407 |
-
}
|
408 |
-
|
409 |
-
var valueRange = Math.abs(maxValue - minValue),
|
410 |
-
rangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),
|
411 |
-
graphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
|
412 |
-
graphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
|
413 |
-
graphRange = graphMax - graphMin,
|
414 |
-
stepValue = Math.pow(10, rangeOrderOfMagnitude),
|
415 |
-
numberOfSteps = Math.round(graphRange / stepValue);
|
416 |
-
|
417 |
-
//If we have more space on the graph we'll use it to give more definition to the data
|
418 |
-
while((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {
|
419 |
-
if(numberOfSteps > maxSteps) {
|
420 |
-
stepValue *=2;
|
421 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
422 |
-
// Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.
|
423 |
-
if (numberOfSteps % 1 !== 0) {
|
424 |
-
skipFitting = true;
|
425 |
-
}
|
426 |
-
}
|
427 |
-
//We can fit in double the amount of scale points on the scale
|
428 |
-
else{
|
429 |
-
//If user has declared ints only, and the step value isn't a decimal
|
430 |
-
if (integersOnly && rangeOrderOfMagnitude >= 0) {
|
431 |
-
//If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float
|
432 |
-
if((numberOfSteps * 5) < maxSteps && stepValue/5 % 1 === 0) {
|
433 |
-
stepValue /=5;
|
434 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
435 |
-
}
|
436 |
-
else if(stepValue/2 % 1 === 0) {
|
437 |
-
stepValue /=2;
|
438 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
439 |
-
}
|
440 |
-
//If it would make it a float break out of the loop
|
441 |
-
else{
|
442 |
-
break;
|
443 |
-
}
|
444 |
-
}
|
445 |
-
//If the scale doesn't have to be an int, make the scale more granular anyway.
|
446 |
-
else{
|
447 |
-
stepValue /=2;
|
448 |
-
numberOfSteps = Math.round(graphRange/stepValue);
|
449 |
-
}
|
450 |
-
|
451 |
-
}
|
452 |
-
}
|
453 |
-
|
454 |
-
if (skipFitting) {
|
455 |
-
numberOfSteps = minSteps;
|
456 |
-
stepValue = graphRange / numberOfSteps;
|
457 |
-
}
|
458 |
-
|
459 |
-
// Drop unnecessary steps
|
460 |
-
if(!startFromZero) {
|
461 |
-
while(minValue > graphMin + stepValue) {
|
462 |
-
numberOfSteps--;
|
463 |
-
graphMin += stepValue;
|
464 |
-
}
|
465 |
-
}
|
466 |
-
|
467 |
-
while(maxValue < graphMax - stepValue) {
|
468 |
-
numberOfSteps--;
|
469 |
-
graphMax -= stepValue;
|
470 |
-
}
|
471 |
-
|
472 |
-
return {
|
473 |
-
steps : numberOfSteps,
|
474 |
-
stepValue : stepValue,
|
475 |
-
min : graphMin,
|
476 |
-
max : graphMin + (numberOfSteps * stepValue)
|
477 |
-
};
|
478 |
-
|
479 |
},
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
template = helpers.template = function (templateString, valuesObject) {
|
485 |
-
// If templateString is function rather than string-template - call the function for valuesObject
|
486 |
-
if(templateString instanceof Function) {
|
487 |
-
return templateString(valuesObject);
|
488 |
-
}
|
489 |
-
|
490 |
-
var cache = {};
|
491 |
-
function tmpl(str, data)
|
492 |
-
{
|
493 |
-
// Figure out if we're getting a template, or if we need to
|
494 |
-
// load the template - and be sure to cache the result.
|
495 |
-
var fn = !/\W/.test(str) ?
|
496 |
-
cache[str] = cache[str] :
|
497 |
-
|
498 |
-
// Generate a reusable function that will serve as a template
|
499 |
-
// generator (and which will be cached).
|
500 |
-
new Function(
|
501 |
-
"obj",
|
502 |
-
"var p=[],print=function(){p.push.apply(p,arguments);};" +
|
503 |
-
|
504 |
-
// Introduce the data as local variables using with(){}
|
505 |
-
"with(obj){p.push('" +
|
506 |
-
|
507 |
-
// Convert the template into pure JavaScript
|
508 |
-
str
|
509 |
-
.replace(/[\r\t\n]/g, " ")
|
510 |
-
.split("<%").join("\t")
|
511 |
-
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
|
512 |
-
.replace(/\t=(.*?)%>/g, "',$1,'")
|
513 |
-
.split("\t").join("');")
|
514 |
-
.split("%>").join("p.push('")
|
515 |
-
.split("\r").join("\\'") +
|
516 |
-
"');}return p.join('');"
|
517 |
-
);
|
518 |
-
|
519 |
-
// Provide some basic currying to the user
|
520 |
-
return data ? fn(data) : fn;
|
521 |
-
}
|
522 |
-
return tmpl(templateString,valuesObject);
|
523 |
},
|
524 |
-
|
525 |
-
|
526 |
-
var labelsArray = new Array(numberOfSteps);
|
527 |
-
if (labelTemplateString) {
|
528 |
-
each(
|
529 |
-
labelsArray,function (val,index) {
|
530 |
-
labelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});
|
531 |
-
}
|
532 |
-
);
|
533 |
-
}
|
534 |
-
return labelsArray;
|
535 |
},
|
536 |
-
|
537 |
-
|
538 |
-
//http://www.robertpenner.com/easing/
|
539 |
-
easingEffects = helpers.easingEffects = {
|
540 |
-
linear: function (t) {
|
541 |
-
return t;
|
542 |
-
},
|
543 |
-
easeInQuad: function (t) {
|
544 |
-
return t * t;
|
545 |
-
},
|
546 |
-
easeOutQuad: function (t) {
|
547 |
-
return -1 * t * (t - 2);
|
548 |
-
},
|
549 |
-
easeInOutQuad: function (t) {
|
550 |
-
if ((t /= 1 / 2) < 1) { return 1 / 2 * t * t;
|
551 |
-
}
|
552 |
-
return -1 / 2 * ((--t) * (t - 2) - 1);
|
553 |
-
},
|
554 |
-
easeInCubic: function (t) {
|
555 |
-
return t * t * t;
|
556 |
-
},
|
557 |
-
easeOutCubic: function (t) {
|
558 |
-
return 1 * ((t = t / 1 - 1) * t * t + 1);
|
559 |
-
},
|
560 |
-
easeInOutCubic: function (t) {
|
561 |
-
if ((t /= 1 / 2) < 1) { return 1 / 2 * t * t * t;
|
562 |
-
}
|
563 |
-
return 1 / 2 * ((t -= 2) * t * t + 2);
|
564 |
-
},
|
565 |
-
easeInQuart: function (t) {
|
566 |
-
return t * t * t * t;
|
567 |
-
},
|
568 |
-
easeOutQuart: function (t) {
|
569 |
-
return -1 * ((t = t / 1 - 1) * t * t * t - 1);
|
570 |
-
},
|
571 |
-
easeInOutQuart: function (t) {
|
572 |
-
if ((t /= 1 / 2) < 1) { return 1 / 2 * t * t * t * t;
|
573 |
-
}
|
574 |
-
return -1 / 2 * ((t -= 2) * t * t * t - 2);
|
575 |
-
},
|
576 |
-
easeInQuint: function (t) {
|
577 |
-
return 1 * (t /= 1) * t * t * t * t;
|
578 |
-
},
|
579 |
-
easeOutQuint: function (t) {
|
580 |
-
return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);
|
581 |
-
},
|
582 |
-
easeInOutQuint: function (t) {
|
583 |
-
if ((t /= 1 / 2) < 1) { return 1 / 2 * t * t * t * t * t;
|
584 |
-
}
|
585 |
-
return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
|
586 |
-
},
|
587 |
-
easeInSine: function (t) {
|
588 |
-
return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
|
589 |
-
},
|
590 |
-
easeOutSine: function (t) {
|
591 |
-
return 1 * Math.sin(t / 1 * (Math.PI / 2));
|
592 |
-
},
|
593 |
-
easeInOutSine: function (t) {
|
594 |
-
return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
|
595 |
-
},
|
596 |
-
easeInExpo: function (t) {
|
597 |
-
return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
|
598 |
-
},
|
599 |
-
easeOutExpo: function (t) {
|
600 |
-
return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
|
601 |
-
},
|
602 |
-
easeInOutExpo: function (t) {
|
603 |
-
if (t === 0) { return 0;
|
604 |
-
}
|
605 |
-
if (t === 1) { return 1;
|
606 |
-
}
|
607 |
-
if ((t /= 1 / 2) < 1) { return 1 / 2 * Math.pow(2, 10 * (t - 1));
|
608 |
-
}
|
609 |
-
return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
|
610 |
-
},
|
611 |
-
easeInCirc: function (t) {
|
612 |
-
if (t >= 1) { return t;
|
613 |
-
}
|
614 |
-
return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
|
615 |
-
},
|
616 |
-
easeOutCirc: function (t) {
|
617 |
-
return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
|
618 |
-
},
|
619 |
-
easeInOutCirc: function (t) {
|
620 |
-
if ((t /= 1 / 2) < 1) { return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
|
621 |
-
}
|
622 |
-
return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
|
623 |
-
},
|
624 |
-
easeInElastic: function (t) {
|
625 |
-
var s = 1.70158;
|
626 |
-
var p = 0;
|
627 |
-
var a = 1;
|
628 |
-
if (t === 0) { return 0;
|
629 |
-
}
|
630 |
-
if ((t /= 1) == 1) { return 1;
|
631 |
-
}
|
632 |
-
if (!p) { p = 1 * 0.3;
|
633 |
-
}
|
634 |
-
if (a < Math.abs(1)) {
|
635 |
-
a = 1;
|
636 |
-
s = p / 4;
|
637 |
-
} else { s = p / (2 * Math.PI) * Math.asin(1 / a);
|
638 |
-
}
|
639 |
-
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
640 |
-
},
|
641 |
-
easeOutElastic: function (t) {
|
642 |
-
var s = 1.70158;
|
643 |
-
var p = 0;
|
644 |
-
var a = 1;
|
645 |
-
if (t === 0) { return 0;
|
646 |
-
}
|
647 |
-
if ((t /= 1) == 1) { return 1;
|
648 |
-
}
|
649 |
-
if (!p) { p = 1 * 0.3;
|
650 |
-
}
|
651 |
-
if (a < Math.abs(1)) {
|
652 |
-
a = 1;
|
653 |
-
s = p / 4;
|
654 |
-
} else { s = p / (2 * Math.PI) * Math.asin(1 / a);
|
655 |
-
}
|
656 |
-
return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
|
657 |
-
},
|
658 |
-
easeInOutElastic: function (t) {
|
659 |
-
var s = 1.70158;
|
660 |
-
var p = 0;
|
661 |
-
var a = 1;
|
662 |
-
if (t === 0) { return 0;
|
663 |
-
}
|
664 |
-
if ((t /= 1 / 2) == 2) { return 1;
|
665 |
-
}
|
666 |
-
if (!p) { p = 1 * (0.3 * 1.5);
|
667 |
-
}
|
668 |
-
if (a < Math.abs(1)) {
|
669 |
-
a = 1;
|
670 |
-
s = p / 4;
|
671 |
-
} else { s = p / (2 * Math.PI) * Math.asin(1 / a);
|
672 |
-
}
|
673 |
-
if (t < 1) { return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
674 |
-
}
|
675 |
-
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
|
676 |
-
},
|
677 |
-
easeInBack: function (t) {
|
678 |
-
var s = 1.70158;
|
679 |
-
return 1 * (t /= 1) * t * ((s + 1) * t - s);
|
680 |
-
},
|
681 |
-
easeOutBack: function (t) {
|
682 |
-
var s = 1.70158;
|
683 |
-
return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
|
684 |
-
},
|
685 |
-
easeInOutBack: function (t) {
|
686 |
-
var s = 1.70158;
|
687 |
-
if ((t /= 1 / 2) < 1) { return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
|
688 |
-
}
|
689 |
-
return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
|
690 |
-
},
|
691 |
-
easeInBounce: function (t) {
|
692 |
-
return 1 - easingEffects.easeOutBounce(1 - t);
|
693 |
-
},
|
694 |
-
easeOutBounce: function (t) {
|
695 |
-
if ((t /= 1) < (1 / 2.75)) {
|
696 |
-
return 1 * (7.5625 * t * t);
|
697 |
-
} else if (t < (2 / 2.75)) {
|
698 |
-
return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
|
699 |
-
} else if (t < (2.5 / 2.75)) {
|
700 |
-
return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
|
701 |
-
} else {
|
702 |
-
return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
|
703 |
-
}
|
704 |
-
},
|
705 |
-
easeInOutBounce: function (t) {
|
706 |
-
if (t < 1 / 2) { return easingEffects.easeInBounce(t * 2) * 0.5;
|
707 |
-
}
|
708 |
-
return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
|
709 |
-
}
|
710 |
},
|
711 |
-
|
712 |
-
|
713 |
-
return window.requestAnimationFrame ||
|
714 |
-
window.webkitRequestAnimationFrame ||
|
715 |
-
window.mozRequestAnimationFrame ||
|
716 |
-
window.oRequestAnimationFrame ||
|
717 |
-
window.msRequestAnimationFrame ||
|
718 |
-
function (callback) {
|
719 |
-
return window.setTimeout(callback, 1000 / 60);
|
720 |
-
};
|
721 |
-
})(),
|
722 |
-
cancelAnimFrame = helpers.cancelAnimFrame = (function () {
|
723 |
-
return window.cancelAnimationFrame ||
|
724 |
-
window.webkitCancelAnimationFrame ||
|
725 |
-
window.mozCancelAnimationFrame ||
|
726 |
-
window.oCancelAnimationFrame ||
|
727 |
-
window.msCancelAnimationFrame ||
|
728 |
-
function (callback) {
|
729 |
-
return window.clearTimeout(callback, 1000 / 60);
|
730 |
-
};
|
731 |
-
})(),
|
732 |
-
animationLoop = helpers.animationLoop = function (callback,totalSteps,easingString,onProgress,onComplete,chartInstance) {
|
733 |
-
|
734 |
-
var currentStep = 0,
|
735 |
-
easingFunction = easingEffects[easingString] || easingEffects.linear;
|
736 |
-
|
737 |
-
var animationFrame = function () {
|
738 |
-
currentStep++;
|
739 |
-
var stepDecimal = currentStep/totalSteps;
|
740 |
-
var easeDecimal = easingFunction(stepDecimal);
|
741 |
-
|
742 |
-
callback.call(chartInstance,easeDecimal,stepDecimal, currentStep);
|
743 |
-
onProgress.call(chartInstance,easeDecimal,stepDecimal);
|
744 |
-
if (currentStep < totalSteps) {
|
745 |
-
chartInstance.animationFrame = requestAnimFrame(animationFrame);
|
746 |
-
} else{
|
747 |
-
onComplete.apply(chartInstance);
|
748 |
-
}
|
749 |
-
};
|
750 |
-
requestAnimFrame(animationFrame);
|
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 |
-
node.removeEventListener(eventType, handler, false);
|
787 |
-
} else if (node.detachEvent) {
|
788 |
-
node.detachEvent("on"+eventType,handler);
|
789 |
-
} else{
|
790 |
-
node["on" + eventType] = noop;
|
791 |
-
}
|
792 |
},
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
each(
|
799 |
-
arrayOfEvents,function (eventName) {
|
800 |
-
chartInstance.events[eventName] = function () {
|
801 |
-
handler.apply(chartInstance, arguments);
|
802 |
-
};
|
803 |
-
addEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);
|
804 |
-
}
|
805 |
-
);
|
806 |
},
|
807 |
-
|
808 |
-
|
809 |
-
arrayOfEvents, function (handler,eventName) {
|
810 |
-
removeEvent(chartInstance.chart.canvas, eventName, handler);
|
811 |
-
}
|
812 |
-
);
|
813 |
},
|
814 |
-
|
815 |
-
|
816 |
-
// TODO = check cross browser stuff with this.
|
817 |
-
return container.clientWidth;
|
818 |
},
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
|
|
|
|
823 |
},
|
824 |
-
|
825 |
-
retinaScale = helpers.retinaScale = function (chart) {
|
826 |
-
var ctx = chart.ctx,
|
827 |
-
width = chart.canvas.width,
|
828 |
-
height = chart.canvas.height;
|
829 |
-
|
830 |
-
if (window.devicePixelRatio) {
|
831 |
-
ctx.canvas.style.width = width + "px";
|
832 |
-
ctx.canvas.style.height = height + "px";
|
833 |
-
ctx.canvas.height = height * window.devicePixelRatio;
|
834 |
-
ctx.canvas.width = width * window.devicePixelRatio;
|
835 |
-
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
|
836 |
-
}
|
837 |
},
|
838 |
-
|
839 |
-
|
840 |
-
chart.ctx.clearRect(0,0,chart.width,chart.height);
|
841 |
},
|
842 |
-
|
843 |
-
|
844 |
},
|
845 |
-
|
846 |
-
|
847 |
-
var longest = 0;
|
848 |
-
each(
|
849 |
-
arrayOfStrings,function (string) {
|
850 |
-
var textWidth = ctx.measureText(string).width;
|
851 |
-
longest = (textWidth > longest) ? textWidth : longest;
|
852 |
-
}
|
853 |
-
);
|
854 |
-
return longest;
|
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 |
}
|
887 |
-
|
888 |
-
};
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
this.options.onAnimationProgress,
|
931 |
-
this.options.onAnimationComplete,
|
932 |
-
this
|
933 |
-
);
|
934 |
-
}
|
935 |
-
else{
|
936 |
-
this.draw();
|
937 |
-
this.options.onAnimationComplete.call(this);
|
938 |
-
}
|
939 |
-
return this;
|
940 |
-
},
|
941 |
-
generateLegend : function () {
|
942 |
-
return template(this.options.legendTemplate,this);
|
943 |
-
},
|
944 |
-
destroy : function () {
|
945 |
-
this.clear();
|
946 |
-
unbindEvents(this, this.events);
|
947 |
-
delete Chart.instances[this.id];
|
948 |
-
},
|
949 |
-
showTooltip : function (ChartElements, forceRedraw) {
|
950 |
-
// Only redraw the chart if we've actually changed what we're hovering on.
|
951 |
-
if (typeof this.activeElements === 'undefined') { this.activeElements = [];
|
952 |
-
}
|
953 |
-
|
954 |
-
var isChanged = (function (Elements) {
|
955 |
-
var changed = false;
|
956 |
-
|
957 |
-
if (Elements.length !== this.activeElements.length) {
|
958 |
-
changed = true;
|
959 |
-
return changed;
|
960 |
-
}
|
961 |
-
|
962 |
-
each(
|
963 |
-
Elements, function (element, index) {
|
964 |
-
if (element !== this.activeElements[index]) {
|
965 |
-
changed = true;
|
966 |
-
}
|
967 |
-
}, this
|
968 |
-
);
|
969 |
-
return changed;
|
970 |
-
}).call(this, ChartElements);
|
971 |
-
|
972 |
-
if (!isChanged && !forceRedraw) {
|
973 |
-
return;
|
974 |
-
}
|
975 |
-
else{
|
976 |
-
this.activeElements = ChartElements;
|
977 |
-
}
|
978 |
-
this.draw();
|
979 |
-
if (ChartElements.length > 0) {
|
980 |
-
// If we have multiple datasets, show a MultiTooltip for all of the data points at that index
|
981 |
-
if (this.datasets && this.datasets.length > 1) {
|
982 |
-
var dataArray,
|
983 |
-
dataIndex;
|
984 |
-
|
985 |
-
for (var i = this.datasets.length - 1; i >= 0; i--) {
|
986 |
-
dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
|
987 |
-
dataIndex = indexOf(dataArray, ChartElements[0]);
|
988 |
-
if (dataIndex !== -1) {
|
989 |
-
break;
|
990 |
-
}
|
991 |
-
}
|
992 |
-
var tooltipLabels = [],
|
993 |
-
tooltipColors = [],
|
994 |
-
medianPosition = (function (index) {
|
995 |
-
|
996 |
-
// Get all the points at that particular index
|
997 |
-
var Elements = [],
|
998 |
-
dataCollection,
|
999 |
-
xPositions = [],
|
1000 |
-
yPositions = [],
|
1001 |
-
xMax,
|
1002 |
-
yMax,
|
1003 |
-
xMin,
|
1004 |
-
yMin;
|
1005 |
-
helpers.each(
|
1006 |
-
this.datasets, function (dataset) {
|
1007 |
-
dataCollection = dataset.points || dataset.bars || dataset.segments;
|
1008 |
-
if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()) {
|
1009 |
-
Elements.push(dataCollection[dataIndex]);
|
1010 |
-
}
|
1011 |
-
}
|
1012 |
-
);
|
1013 |
-
|
1014 |
-
helpers.each(
|
1015 |
-
Elements, function (element) {
|
1016 |
-
xPositions.push(element.x);
|
1017 |
-
yPositions.push(element.y);
|
1018 |
-
|
1019 |
-
|
1020 |
-
//Include any colour information about the element
|
1021 |
-
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
|
1022 |
-
tooltipColors.push(
|
1023 |
-
{
|
1024 |
-
fill: element._saved.fillColor || element.fillColor,
|
1025 |
-
stroke: element._saved.strokeColor || element.strokeColor
|
1026 |
-
}
|
1027 |
-
);
|
1028 |
-
|
1029 |
-
}, this
|
1030 |
-
);
|
1031 |
-
|
1032 |
-
yMin = min(yPositions);
|
1033 |
-
yMax = max(yPositions);
|
1034 |
-
|
1035 |
-
xMin = min(xPositions);
|
1036 |
-
xMax = max(xPositions);
|
1037 |
-
|
1038 |
-
return {
|
1039 |
-
x: (xMin > this.chart.width/2) ? xMin : xMax,
|
1040 |
-
y: (yMin + yMax)/2
|
1041 |
-
};
|
1042 |
-
}).call(this, dataIndex);
|
1043 |
-
|
1044 |
-
new Chart.MultiTooltip(
|
1045 |
-
{
|
1046 |
-
x: medianPosition.x,
|
1047 |
-
y: medianPosition.y,
|
1048 |
-
xPadding: this.options.tooltipXPadding,
|
1049 |
-
yPadding: this.options.tooltipYPadding,
|
1050 |
-
xOffset: this.options.tooltipXOffset,
|
1051 |
-
fillColor: this.options.tooltipFillColor,
|
1052 |
-
textColor: this.options.tooltipFontColor,
|
1053 |
-
fontFamily: this.options.tooltipFontFamily,
|
1054 |
-
fontStyle: this.options.tooltipFontStyle,
|
1055 |
-
fontSize: this.options.tooltipFontSize,
|
1056 |
-
titleTextColor: this.options.tooltipTitleFontColor,
|
1057 |
-
titleFontFamily: this.options.tooltipTitleFontFamily,
|
1058 |
-
titleFontStyle: this.options.tooltipTitleFontStyle,
|
1059 |
-
titleFontSize: this.options.tooltipTitleFontSize,
|
1060 |
-
cornerRadius: this.options.tooltipCornerRadius,
|
1061 |
-
labels: tooltipLabels,
|
1062 |
-
legendColors: tooltipColors,
|
1063 |
-
legendColorBackground : this.options.multiTooltipKeyBackground,
|
1064 |
-
title: ChartElements[0].label,
|
1065 |
-
chart: this.chart,
|
1066 |
-
ctx: this.chart.ctx
|
1067 |
-
}
|
1068 |
-
).draw();
|
1069 |
-
|
1070 |
-
} else {
|
1071 |
-
each(
|
1072 |
-
ChartElements, function (Element) {
|
1073 |
-
var tooltipPosition = Element.tooltipPosition();
|
1074 |
-
new Chart.Tooltip(
|
1075 |
-
{
|
1076 |
-
x: Math.round(tooltipPosition.x),
|
1077 |
-
y: Math.round(tooltipPosition.y),
|
1078 |
-
xPadding: this.options.tooltipXPadding,
|
1079 |
-
yPadding: this.options.tooltipYPadding,
|
1080 |
-
fillColor: this.options.tooltipFillColor,
|
1081 |
-
textColor: this.options.tooltipFontColor,
|
1082 |
-
fontFamily: this.options.tooltipFontFamily,
|
1083 |
-
fontStyle: this.options.tooltipFontStyle,
|
1084 |
-
fontSize: this.options.tooltipFontSize,
|
1085 |
-
caretHeight: this.options.tooltipCaretSize,
|
1086 |
-
cornerRadius: this.options.tooltipCornerRadius,
|
1087 |
-
text: template(this.options.tooltipTemplate, Element),
|
1088 |
-
chart: this.chart
|
1089 |
-
}
|
1090 |
-
).draw();
|
1091 |
-
}, this
|
1092 |
-
);
|
1093 |
-
}
|
1094 |
-
}
|
1095 |
-
return this;
|
1096 |
-
},
|
1097 |
-
toBase64Image : function () {
|
1098 |
-
return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
|
1099 |
-
}
|
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 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1140 |
}
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
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 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
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 |
}
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
draw : function (animationPercent) {
|
1281 |
-
|
1282 |
-
var easingDecimal = animationPercent || 1;
|
1283 |
-
|
1284 |
-
var ctx = this.ctx;
|
1285 |
-
|
1286 |
-
ctx.beginPath();
|
1287 |
-
|
1288 |
-
ctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle);
|
1289 |
-
|
1290 |
-
ctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true);
|
1291 |
-
|
1292 |
-
ctx.closePath();
|
1293 |
-
ctx.strokeStyle = this.strokeColor;
|
1294 |
-
ctx.lineWidth = this.strokeWidth;
|
1295 |
-
|
1296 |
-
ctx.fillStyle = this.fillColor;
|
1297 |
-
|
1298 |
-
ctx.fill();
|
1299 |
-
ctx.lineJoin = 'bevel';
|
1300 |
-
|
1301 |
-
if (this.showStroke) {
|
1302 |
-
ctx.stroke();
|
1303 |
-
}
|
1304 |
-
}
|
1305 |
}
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
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 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1428 |
}
|
1429 |
-
|
1430 |
-
|
1431 |
-
Chart.MultiTooltip = Chart.Element.extend(
|
1432 |
-
{
|
1433 |
-
initialize : function () {
|
1434 |
-
this.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
|
1435 |
-
|
1436 |
-
this.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily);
|
1437 |
-
|
1438 |
-
this.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5;
|
1439 |
-
|
1440 |
-
this.ctx.font = this.titleFont;
|
1441 |
-
|
1442 |
-
var titleWidth = this.ctx.measureText(this.title).width,
|
1443 |
-
//Label has a legend square as well so account for this.
|
1444 |
-
labelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,
|
1445 |
-
longestTextWidth = max([labelWidth,titleWidth]);
|
1446 |
-
|
1447 |
-
this.width = longestTextWidth + (this.xPadding*2);
|
1448 |
-
|
1449 |
-
|
1450 |
-
var halfHeight = this.height/2;
|
1451 |
-
|
1452 |
-
//Check to ensure the height will fit on the canvas
|
1453 |
-
//The three is to buffer form the very
|
1454 |
-
if (this.y - halfHeight < 0 ) {
|
1455 |
-
this.y = halfHeight;
|
1456 |
-
} else if (this.y + halfHeight > this.chart.height) {
|
1457 |
-
this.y = this.chart.height - halfHeight;
|
1458 |
-
}
|
1459 |
-
|
1460 |
-
//Decide whether to align left or right based on position on canvas
|
1461 |
-
if (this.x > this.chart.width/2) {
|
1462 |
-
this.x -= this.xOffset + this.width;
|
1463 |
-
} else {
|
1464 |
-
this.x += this.xOffset;
|
1465 |
-
}
|
1466 |
-
|
1467 |
-
|
1468 |
-
},
|
1469 |
-
getLineHeight : function (index) {
|
1470 |
-
var baseLineHeight = this.y - (this.height/2) + this.yPadding,
|
1471 |
-
afterTitleIndex = index-1;
|
1472 |
-
|
1473 |
-
//If the index is zero, we're getting the title
|
1474 |
-
if (index === 0) {
|
1475 |
-
return baseLineHeight + this.titleFontSize/2;
|
1476 |
-
} else{
|
1477 |
-
return baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5;
|
1478 |
-
}
|
1479 |
-
|
1480 |
-
},
|
1481 |
-
draw : function () {
|
1482 |
-
drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);
|
1483 |
-
var ctx = this.ctx;
|
1484 |
-
ctx.fillStyle = this.fillColor;
|
1485 |
-
ctx.fill();
|
1486 |
-
ctx.closePath();
|
1487 |
-
|
1488 |
-
ctx.textAlign = "left";
|
1489 |
-
ctx.textBaseline = "middle";
|
1490 |
-
ctx.fillStyle = this.titleTextColor;
|
1491 |
-
ctx.font = this.titleFont;
|
1492 |
-
|
1493 |
-
ctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));
|
1494 |
-
|
1495 |
-
ctx.font = this.font;
|
1496 |
-
helpers.each(
|
1497 |
-
this.labels,function (label,index) {
|
1498 |
-
ctx.fillStyle = this.textColor;
|
1499 |
-
ctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));
|
1500 |
-
|
1501 |
-
//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)
|
1502 |
-
//ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1503 |
-
//Instead we'll make a white filled block to put the legendColour palette over.
|
1504 |
-
|
1505 |
-
ctx.fillStyle = this.legendColorBackground;
|
1506 |
-
ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1507 |
-
|
1508 |
-
ctx.fillStyle = this.legendColors[index].fill;
|
1509 |
-
ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
|
1510 |
-
|
1511 |
-
|
1512 |
-
},this
|
1513 |
-
);
|
1514 |
-
}
|
1515 |
}
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
-
|
1527 |
-
|
1528 |
-
|
1529 |
-
|
1530 |
-
|
1531 |
-
|
1532 |
-
|
1533 |
-
|
1534 |
-
this.xLabels.push(label);
|
1535 |
-
this.valuesCount++;
|
1536 |
-
this.fit();
|
1537 |
-
},
|
1538 |
-
removeXLabel : function () {
|
1539 |
-
this.xLabels.shift();
|
1540 |
-
this.valuesCount--;
|
1541 |
-
this.fit();
|
1542 |
-
},
|
1543 |
-
// Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use
|
1544 |
-
fit: function () {
|
1545 |
-
// First we need the width of the yLabels, assuming the xLabels aren't rotated
|
1546 |
-
|
1547 |
-
// To do that we need the base line at the top and base of the chart, assuming there is no x label rotation
|
1548 |
-
this.startPoint = (this.display) ? this.fontSize : 0;
|
1549 |
-
this.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels
|
1550 |
-
|
1551 |
-
// Apply padding settings to the start and end point.
|
1552 |
-
this.startPoint += this.padding;
|
1553 |
-
this.endPoint -= this.padding;
|
1554 |
-
|
1555 |
-
// Cache the starting height, so can determine if we need to recalculate the scale yAxis
|
1556 |
-
var cachedHeight = this.endPoint - this.startPoint,
|
1557 |
-
cachedYLabelWidth;
|
1558 |
-
|
1559 |
-
// Build the current yLabels so we have an idea of what size they'll be to start
|
1560 |
-
/*
|
1561 |
-
* This sets what is returned from calculateScaleRange as static properties of this class:
|
1562 |
-
*
|
1563 |
-
this.steps;
|
1564 |
-
this.stepValue;
|
1565 |
-
this.min;
|
1566 |
-
this.max;
|
1567 |
-
*
|
1568 |
-
*/
|
1569 |
-
this.calculateYRange(cachedHeight);
|
1570 |
-
|
1571 |
-
// With these properties set we can now build the array of yLabels
|
1572 |
-
// and also the width of the largest yLabel
|
1573 |
-
this.buildYLabels();
|
1574 |
-
|
1575 |
-
this.calculateXLabelRotation();
|
1576 |
-
|
1577 |
-
while((cachedHeight > this.endPoint - this.startPoint)){
|
1578 |
-
cachedHeight = this.endPoint - this.startPoint;
|
1579 |
-
cachedYLabelWidth = this.yLabelWidth;
|
1580 |
-
|
1581 |
-
this.calculateYRange(cachedHeight);
|
1582 |
-
this.buildYLabels();
|
1583 |
-
|
1584 |
-
// Only go through the xLabel loop again if the yLabel width has changed
|
1585 |
-
if (cachedYLabelWidth < this.yLabelWidth) {
|
1586 |
-
this.calculateXLabelRotation();
|
1587 |
-
}
|
1588 |
-
}
|
1589 |
-
|
1590 |
-
},
|
1591 |
-
calculateXLabelRotation : function () {
|
1592 |
-
//Get the width of each grid by calculating the difference
|
1593 |
-
//between x offsets between 0 and 1.
|
1594 |
-
|
1595 |
-
this.ctx.font = this.font;
|
1596 |
-
|
1597 |
-
var firstWidth = this.ctx.measureText(this.xLabels[0]).width,
|
1598 |
-
lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,
|
1599 |
-
firstRotated,
|
1600 |
-
lastRotated;
|
1601 |
-
|
1602 |
-
|
1603 |
-
this.xScalePaddingRight = lastWidth/2 + 3;
|
1604 |
-
this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10;
|
1605 |
-
|
1606 |
-
this.xLabelRotation = 0;
|
1607 |
-
if (this.display) {
|
1608 |
-
var originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),
|
1609 |
-
cosRotation,
|
1610 |
-
firstRotatedWidth;
|
1611 |
-
this.xLabelWidth = originalLabelWidth;
|
1612 |
-
//Allow 3 pixels x2 padding either side for label readability
|
1613 |
-
var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;
|
1614 |
-
|
1615 |
-
//Max label rotate should be 90 - also act as a loop counter
|
1616 |
-
while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){
|
1617 |
-
cosRotation = Math.cos(toRadians(this.xLabelRotation));
|
1618 |
-
|
1619 |
-
firstRotated = cosRotation * firstWidth;
|
1620 |
-
lastRotated = cosRotation * lastWidth;
|
1621 |
-
|
1622 |
-
// We're right aligning the text now.
|
1623 |
-
if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8) {
|
1624 |
-
this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
|
1625 |
-
}
|
1626 |
-
this.xScalePaddingRight = this.fontSize/2;
|
1627 |
-
|
1628 |
-
|
1629 |
-
this.xLabelRotation++;
|
1630 |
-
this.xLabelWidth = cosRotation * originalLabelWidth;
|
1631 |
-
|
1632 |
-
}
|
1633 |
-
if (this.xLabelRotation > 0) {
|
1634 |
-
this.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;
|
1635 |
-
}
|
1636 |
-
}
|
1637 |
-
else{
|
1638 |
-
this.xLabelWidth = 0;
|
1639 |
-
this.xScalePaddingRight = this.padding;
|
1640 |
-
this.xScalePaddingLeft = this.padding;
|
1641 |
-
}
|
1642 |
-
|
1643 |
-
},
|
1644 |
-
// Needs to be overidden in each Chart type
|
1645 |
-
// Otherwise we need to pass all the data into the scale class
|
1646 |
-
calculateYRange: noop,
|
1647 |
-
drawingArea: function () {
|
1648 |
-
return this.startPoint - this.endPoint;
|
1649 |
-
},
|
1650 |
-
calculateY : function (value) {
|
1651 |
-
var scalingFactor = this.drawingArea() / (this.min - this.max);
|
1652 |
-
return this.endPoint - (scalingFactor * (value - this.min));
|
1653 |
-
},
|
1654 |
-
calculateX : function (index) {
|
1655 |
-
var isRotated = (this.xLabelRotation > 0),
|
1656 |
-
// innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,
|
1657 |
-
innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
|
1658 |
-
valueWidth = innerWidth/(this.valuesCount - ((this.offsetGridLines) ? 0 : 1)),
|
1659 |
-
valueOffset = (valueWidth * index) + this.xScalePaddingLeft;
|
1660 |
-
|
1661 |
-
if (this.offsetGridLines) {
|
1662 |
-
valueOffset += (valueWidth/2);
|
1663 |
-
}
|
1664 |
-
|
1665 |
-
return Math.round(valueOffset);
|
1666 |
-
},
|
1667 |
-
update : function (newProps) {
|
1668 |
-
helpers.extend(this, newProps);
|
1669 |
-
this.fit();
|
1670 |
-
},
|
1671 |
-
draw : function () {
|
1672 |
-
var ctx = this.ctx,
|
1673 |
-
yLabelGap = (this.endPoint - this.startPoint) / this.steps,
|
1674 |
-
xStart = Math.round(this.xScalePaddingLeft);
|
1675 |
-
if (this.display) {
|
1676 |
-
ctx.fillStyle = this.textColor;
|
1677 |
-
ctx.font = this.font;
|
1678 |
-
each(
|
1679 |
-
this.yLabels,function (labelString,index) {
|
1680 |
-
var yLabelCenter = this.endPoint - (yLabelGap * index),
|
1681 |
-
linePositionY = Math.round(yLabelCenter);
|
1682 |
-
|
1683 |
-
ctx.textAlign = "right";
|
1684 |
-
ctx.textBaseline = "middle";
|
1685 |
-
if (this.showLabels) {
|
1686 |
-
ctx.fillText(labelString,xStart - 10,yLabelCenter);
|
1687 |
-
}
|
1688 |
-
ctx.beginPath();
|
1689 |
-
if (index > 0) {
|
1690 |
-
// This is a grid line in the centre, so drop that
|
1691 |
-
ctx.lineWidth = this.gridLineWidth;
|
1692 |
-
ctx.strokeStyle = this.gridLineColor;
|
1693 |
-
} else {
|
1694 |
-
// This is the first line on the scale
|
1695 |
-
ctx.lineWidth = this.lineWidth;
|
1696 |
-
ctx.strokeStyle = this.lineColor;
|
1697 |
-
}
|
1698 |
-
|
1699 |
-
linePositionY += helpers.aliasPixel(ctx.lineWidth);
|
1700 |
-
|
1701 |
-
ctx.moveTo(xStart, linePositionY);
|
1702 |
-
ctx.lineTo(this.width, linePositionY);
|
1703 |
-
ctx.stroke();
|
1704 |
-
ctx.closePath();
|
1705 |
-
|
1706 |
-
ctx.lineWidth = this.lineWidth;
|
1707 |
-
ctx.strokeStyle = this.lineColor;
|
1708 |
-
ctx.beginPath();
|
1709 |
-
ctx.moveTo(xStart - 5, linePositionY);
|
1710 |
-
ctx.lineTo(xStart, linePositionY);
|
1711 |
-
ctx.stroke();
|
1712 |
-
ctx.closePath();
|
1713 |
-
|
1714 |
-
},this
|
1715 |
-
);
|
1716 |
-
|
1717 |
-
if(this.limitXLabels) {
|
1718 |
-
var xDrawEvery = Math.round(this.xLabels.length / (this.limitXLabelsTo-1));
|
1719 |
-
}
|
1720 |
-
else {
|
1721 |
-
var xDrawEvery = 1;
|
1722 |
-
}
|
1723 |
-
|
1724 |
-
each(
|
1725 |
-
this.xLabels,function (label,index) {
|
1726 |
-
var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
|
1727 |
-
// Check to see if line/bar here and decide where to place the line
|
1728 |
-
linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
|
1729 |
-
isRotated = (this.xLabelRotation > 0);
|
1730 |
-
|
1731 |
-
ctx.beginPath();
|
1732 |
-
|
1733 |
-
if (index > 0) {
|
1734 |
-
// This is a grid line in the centre, so drop that
|
1735 |
-
ctx.lineWidth = this.gridLineWidth;
|
1736 |
-
ctx.strokeStyle = this.gridLineColor;
|
1737 |
-
} else {
|
1738 |
-
// This is the first line on the scale
|
1739 |
-
ctx.lineWidth = this.lineWidth;
|
1740 |
-
ctx.strokeStyle = this.lineColor;
|
1741 |
-
}
|
1742 |
-
if(index == 0 || (index+1) % xDrawEvery == 0 || index == this.xLabels.length-1) {
|
1743 |
-
ctx.moveTo(linePos,this.endPoint);
|
1744 |
-
ctx.lineTo(linePos,this.startPoint - 3);
|
1745 |
-
ctx.stroke();
|
1746 |
-
ctx.closePath();
|
1747 |
-
}
|
1748 |
-
|
1749 |
-
ctx.lineWidth = this.lineWidth;
|
1750 |
-
ctx.strokeStyle = this.lineColor;
|
1751 |
-
|
1752 |
-
|
1753 |
-
// Small lines at the bottom of the base grid line
|
1754 |
-
ctx.beginPath();
|
1755 |
-
ctx.moveTo(linePos,this.endPoint);
|
1756 |
-
ctx.lineTo(linePos,this.endPoint + 5);
|
1757 |
-
ctx.stroke();
|
1758 |
-
ctx.closePath();
|
1759 |
-
|
1760 |
-
ctx.save();
|
1761 |
-
ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);
|
1762 |
-
ctx.rotate(toRadians(this.xLabelRotation)*-1);
|
1763 |
-
ctx.font = this.font;
|
1764 |
-
ctx.textAlign = (isRotated) ? "right" : "center";
|
1765 |
-
ctx.textBaseline = (isRotated) ? "middle" : "top";
|
1766 |
-
ctx.fillText(label, 0, 0);
|
1767 |
-
ctx.restore();
|
1768 |
-
},this
|
1769 |
-
);
|
1770 |
-
|
1771 |
-
}
|
1772 |
-
}
|
1773 |
-
|
1774 |
}
|
1775 |
-
|
1776 |
-
|
1777 |
-
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
},
|
1783 |
-
calculateCenterOffset: function (value) {
|
1784 |
-
// Take into account half font size + the yPadding of the top value
|
1785 |
-
var scalingFactor = this.drawingArea / (this.max - this.min);
|
1786 |
-
|
1787 |
-
return (value - this.min) * scalingFactor;
|
1788 |
-
},
|
1789 |
-
update : function () {
|
1790 |
-
if (!this.lineArc) {
|
1791 |
-
this.setScaleSize();
|
1792 |
-
} else {
|
1793 |
-
this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
|
1794 |
-
}
|
1795 |
-
this.buildYLabels();
|
1796 |
-
},
|
1797 |
-
buildYLabels: function () {
|
1798 |
-
this.yLabels = [];
|
1799 |
-
|
1800 |
-
var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
|
1801 |
-
|
1802 |
-
for (var i=0; i<=this.steps; i++){
|
1803 |
-
this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
|
1804 |
-
}
|
1805 |
-
},
|
1806 |
-
getCircumference : function () {
|
1807 |
-
return ((Math.PI*2) / this.valuesCount);
|
1808 |
-
},
|
1809 |
-
setScaleSize: function () {
|
1810 |
-
/*
|
1811 |
-
* Right, this is really confusing and there is a lot of maths going on here
|
1812 |
-
* The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
|
1813 |
-
*
|
1814 |
-
* Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
|
1815 |
-
*
|
1816 |
-
* Solution:
|
1817 |
-
*
|
1818 |
-
* We assume the radius of the polygon is half the size of the canvas at first
|
1819 |
-
* at each index we check if the text overlaps.
|
1820 |
-
*
|
1821 |
-
* Where it does, we store that angle and that index.
|
1822 |
-
*
|
1823 |
-
* After finding the largest index and angle we calculate how much we need to remove
|
1824 |
-
* from the shape radius to move the point inwards by that x.
|
1825 |
-
*
|
1826 |
-
* We average the left and right distances to get the maximum shape radius that can fit in the box
|
1827 |
-
* along with labels.
|
1828 |
-
*
|
1829 |
-
* Once we have that, we can find the centre point for the chart, by taking the x text protrusion
|
1830 |
-
* on each side, removing that from the size, halving it and adding the left x protrusion width.
|
1831 |
-
*
|
1832 |
-
* This will mean we have a shape fitted to the canvas, as large as it can be with the labels
|
1833 |
-
* and position it in the most space efficient manner
|
1834 |
-
*
|
1835 |
-
* https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
|
1836 |
-
*/
|
1837 |
-
|
1838 |
-
|
1839 |
-
// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
|
1840 |
-
// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
|
1841 |
-
var largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),
|
1842 |
-
pointPosition,
|
1843 |
-
i,
|
1844 |
-
textWidth,
|
1845 |
-
halfTextWidth,
|
1846 |
-
furthestRight = this.width,
|
1847 |
-
furthestRightIndex,
|
1848 |
-
furthestRightAngle,
|
1849 |
-
furthestLeft = 0,
|
1850 |
-
furthestLeftIndex,
|
1851 |
-
furthestLeftAngle,
|
1852 |
-
xProtrusionLeft,
|
1853 |
-
xProtrusionRight,
|
1854 |
-
radiusReductionRight,
|
1855 |
-
radiusReductionLeft,
|
1856 |
-
maxWidthRadius;
|
1857 |
-
this.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
|
1858 |
-
for (i=0;i<this.valuesCount;i++){
|
1859 |
-
// 5px to space the text slightly out - similar to what we do in the draw function.
|
1860 |
-
pointPosition = this.getPointPosition(i, largestPossibleRadius);
|
1861 |
-
textWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;
|
1862 |
-
if (i === 0 || i === this.valuesCount/2) {
|
1863 |
-
// If we're at index zero, or exactly the middle, we're at exactly the top/bottom
|
1864 |
-
// of the radar chart, so text will be aligned centrally, so we'll half it and compare
|
1865 |
-
// w/left and right text sizes
|
1866 |
-
halfTextWidth = textWidth/2;
|
1867 |
-
if (pointPosition.x + halfTextWidth > furthestRight) {
|
1868 |
-
furthestRight = pointPosition.x + halfTextWidth;
|
1869 |
-
furthestRightIndex = i;
|
1870 |
-
}
|
1871 |
-
if (pointPosition.x - halfTextWidth < furthestLeft) {
|
1872 |
-
furthestLeft = pointPosition.x - halfTextWidth;
|
1873 |
-
furthestLeftIndex = i;
|
1874 |
-
}
|
1875 |
-
}
|
1876 |
-
else if (i < this.valuesCount/2) {
|
1877 |
-
// Less than half the values means we'll left align the text
|
1878 |
-
if (pointPosition.x + textWidth > furthestRight) {
|
1879 |
-
furthestRight = pointPosition.x + textWidth;
|
1880 |
-
furthestRightIndex = i;
|
1881 |
-
}
|
1882 |
-
}
|
1883 |
-
else if (i > this.valuesCount/2) {
|
1884 |
-
// More than half the values means we'll right align the text
|
1885 |
-
if (pointPosition.x - textWidth < furthestLeft) {
|
1886 |
-
furthestLeft = pointPosition.x - textWidth;
|
1887 |
-
furthestLeftIndex = i;
|
1888 |
-
}
|
1889 |
-
}
|
1890 |
-
}
|
1891 |
-
|
1892 |
-
xProtrusionLeft = furthestLeft;
|
1893 |
-
|
1894 |
-
xProtrusionRight = Math.ceil(furthestRight - this.width);
|
1895 |
-
|
1896 |
-
furthestRightAngle = this.getIndexAngle(furthestRightIndex);
|
1897 |
-
|
1898 |
-
furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);
|
1899 |
-
|
1900 |
-
radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);
|
1901 |
-
|
1902 |
-
radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);
|
1903 |
-
|
1904 |
-
// Ensure we actually need to reduce the size of the chart
|
1905 |
-
radiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;
|
1906 |
-
radiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;
|
1907 |
-
|
1908 |
-
this.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;
|
1909 |
-
|
1910 |
-
//this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])
|
1911 |
-
this.setCenterPoint(radiusReductionLeft, radiusReductionRight);
|
1912 |
-
|
1913 |
-
},
|
1914 |
-
setCenterPoint: function (leftMovement, rightMovement) {
|
1915 |
-
|
1916 |
-
var maxRight = this.width - rightMovement - this.drawingArea,
|
1917 |
-
maxLeft = leftMovement + this.drawingArea;
|
1918 |
-
|
1919 |
-
this.xCenter = (maxLeft + maxRight)/2;
|
1920 |
-
// Always vertically in the centre as the text height doesn't change
|
1921 |
-
this.yCenter = (this.height/2);
|
1922 |
-
},
|
1923 |
-
|
1924 |
-
getIndexAngle : function (index) {
|
1925 |
-
var angleMultiplier = (Math.PI * 2) / this.valuesCount;
|
1926 |
-
// Start from the top instead of right, so remove a quarter of the circle
|
1927 |
-
|
1928 |
-
return index * angleMultiplier - (Math.PI/2);
|
1929 |
-
},
|
1930 |
-
getPointPosition : function (index, distanceFromCenter) {
|
1931 |
-
var thisAngle = this.getIndexAngle(index);
|
1932 |
-
return {
|
1933 |
-
x : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,
|
1934 |
-
y : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter
|
1935 |
-
};
|
1936 |
-
},
|
1937 |
-
draw: function () {
|
1938 |
-
if (this.display) {
|
1939 |
-
var ctx = this.ctx;
|
1940 |
-
each(
|
1941 |
-
this.yLabels, function (label, index) {
|
1942 |
-
// Don't draw a centre value
|
1943 |
-
if (index > 0) {
|
1944 |
-
var yCenterOffset = index * (this.drawingArea/this.steps),
|
1945 |
-
yHeight = this.yCenter - yCenterOffset,
|
1946 |
-
pointPosition;
|
1947 |
-
|
1948 |
-
// Draw circular lines around the scale
|
1949 |
-
if (this.lineWidth > 0) {
|
1950 |
-
ctx.strokeStyle = this.lineColor;
|
1951 |
-
ctx.lineWidth = this.lineWidth;
|
1952 |
-
|
1953 |
-
if(this.lineArc) {
|
1954 |
-
ctx.beginPath();
|
1955 |
-
ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);
|
1956 |
-
ctx.closePath();
|
1957 |
-
ctx.stroke();
|
1958 |
-
} else{
|
1959 |
-
ctx.beginPath();
|
1960 |
-
for (var i=0;i<this.valuesCount;i++)
|
1961 |
-
{
|
1962 |
-
pointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));
|
1963 |
-
if (i === 0) {
|
1964 |
-
ctx.moveTo(pointPosition.x, pointPosition.y);
|
1965 |
-
} else {
|
1966 |
-
ctx.lineTo(pointPosition.x, pointPosition.y);
|
1967 |
-
}
|
1968 |
-
}
|
1969 |
-
ctx.closePath();
|
1970 |
-
ctx.stroke();
|
1971 |
-
}
|
1972 |
-
}
|
1973 |
-
if(this.showLabels) {
|
1974 |
-
ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
|
1975 |
-
if (this.showLabelBackdrop) {
|
1976 |
-
var labelWidth = ctx.measureText(label).width;
|
1977 |
-
ctx.fillStyle = this.backdropColor;
|
1978 |
-
ctx.fillRect(
|
1979 |
-
this.xCenter - labelWidth/2 - this.backdropPaddingX,
|
1980 |
-
yHeight - this.fontSize/2 - this.backdropPaddingY,
|
1981 |
-
labelWidth + this.backdropPaddingX*2,
|
1982 |
-
this.fontSize + this.backdropPaddingY*2
|
1983 |
-
);
|
1984 |
-
}
|
1985 |
-
ctx.textAlign = 'center';
|
1986 |
-
ctx.textBaseline = "middle";
|
1987 |
-
ctx.fillStyle = this.fontColor;
|
1988 |
-
ctx.fillText(label, this.xCenter, yHeight);
|
1989 |
-
}
|
1990 |
-
}
|
1991 |
-
}, this
|
1992 |
-
);
|
1993 |
-
|
1994 |
-
if (!this.lineArc) {
|
1995 |
-
ctx.lineWidth = this.angleLineWidth;
|
1996 |
-
ctx.strokeStyle = this.angleLineColor;
|
1997 |
-
for (var i = this.valuesCount - 1; i >= 0; i--) {
|
1998 |
-
if (this.angleLineWidth > 0) {
|
1999 |
-
var outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max));
|
2000 |
-
ctx.beginPath();
|
2001 |
-
ctx.moveTo(this.xCenter, this.yCenter);
|
2002 |
-
ctx.lineTo(outerPosition.x, outerPosition.y);
|
2003 |
-
ctx.stroke();
|
2004 |
-
ctx.closePath();
|
2005 |
-
}
|
2006 |
-
// Extra 3px out for some label spacing
|
2007 |
-
var pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5);
|
2008 |
-
ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
|
2009 |
-
ctx.fillStyle = this.pointLabelFontColor;
|
2010 |
-
|
2011 |
-
var labelsCount = this.labels.length,
|
2012 |
-
halfLabelsCount = this.labels.length/2,
|
2013 |
-
quarterLabelsCount = halfLabelsCount/2,
|
2014 |
-
upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
|
2015 |
-
exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
|
2016 |
-
if (i === 0) {
|
2017 |
-
ctx.textAlign = 'center';
|
2018 |
-
} else if(i === halfLabelsCount) {
|
2019 |
-
ctx.textAlign = 'center';
|
2020 |
-
} else if (i < halfLabelsCount) {
|
2021 |
-
ctx.textAlign = 'left';
|
2022 |
-
} else {
|
2023 |
-
ctx.textAlign = 'right';
|
2024 |
-
}
|
2025 |
-
|
2026 |
-
// Set the correct text baseline based on outer positioning
|
2027 |
-
if (exactQuarter) {
|
2028 |
-
ctx.textBaseline = 'middle';
|
2029 |
-
} else if (upperHalf) {
|
2030 |
-
ctx.textBaseline = 'bottom';
|
2031 |
-
} else {
|
2032 |
-
ctx.textBaseline = 'top';
|
2033 |
-
}
|
2034 |
-
|
2035 |
-
ctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);
|
2036 |
-
}
|
2037 |
-
}
|
2038 |
-
}
|
2039 |
-
}
|
2040 |
}
|
2041 |
-
|
2042 |
-
|
2043 |
-
|
2044 |
-
|
2045 |
-
|
2046 |
-
|
2047 |
-
|
2048 |
-
|
2049 |
-
|
2050 |
-
|
2051 |
-
|
2052 |
-
|
2053 |
-
|
2054 |
-
|
2055 |
-
|
2056 |
-
|
2057 |
-
|
2058 |
-
|
2059 |
-
|
2060 |
-
|
2061 |
-
|
2062 |
-
);
|
2063 |
-
};
|
2064 |
-
})()
|
2065 |
-
);
|
2066 |
-
|
2067 |
-
|
2068 |
-
if (amd) {
|
2069 |
-
define(
|
2070 |
-
function () {
|
2071 |
-
return Chart;
|
2072 |
-
}
|
2073 |
-
);
|
2074 |
-
} else if (typeof module === 'object' && module.exports) {
|
2075 |
-
module.exports = Chart;
|
2076 |
}
|
2077 |
-
|
2078 |
-
|
2079 |
-
|
2080 |
-
|
2081 |
-
|
2082 |
-
|
2083 |
-
|
2084 |
-
|
2085 |
-
|
2086 |
-
|
2087 |
-
|
2088 |
-
|
2089 |
-
|
2090 |
-
|
2091 |
-
|
2092 |
-
|
2093 |
-
|
2094 |
-
|
2095 |
-
|
2096 |
-
|
2097 |
-
|
2098 |
-
|
2099 |
-
|
2100 |
-
|
2101 |
-
|
2102 |
-
|
2103 |
-
|
2104 |
-
|
2105 |
-
|
2106 |
-
|
2107 |
-
|
2108 |
-
|
2109 |
-
|
2110 |
-
|
2111 |
-
//Number - Pixel width of the bar stroke
|
2112 |
-
barStrokeWidth : 2,
|
2113 |
-
|
2114 |
-
//Number - Spacing between each of the X value sets
|
2115 |
-
barValueSpacing : 5,
|
2116 |
-
|
2117 |
-
//Number - Spacing between data sets within X values
|
2118 |
-
barDatasetSpacing : 1,
|
2119 |
-
|
2120 |
-
//String - A legend template
|
2121 |
-
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>"
|
2122 |
-
|
2123 |
-
};
|
2124 |
-
|
2125 |
-
|
2126 |
-
Chart.Type.extend(
|
2127 |
-
{
|
2128 |
-
name: "Bar",
|
2129 |
-
defaults : defaultConfig,
|
2130 |
-
initialize: function (data) {
|
2131 |
-
|
2132 |
-
//Expose options as a scope variable here so we can access it in the ScaleClass
|
2133 |
-
var options = this.options;
|
2134 |
-
|
2135 |
-
this.ScaleClass = Chart.Scale.extend(
|
2136 |
-
{
|
2137 |
-
offsetGridLines : true,
|
2138 |
-
calculateBarX : function (datasetCount, datasetIndex, barIndex) {
|
2139 |
-
//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
|
2140 |
-
var xWidth = this.calculateBaseWidth(),
|
2141 |
-
xAbsolute = this.calculateX(barIndex) - (xWidth/2),
|
2142 |
-
barWidth = this.calculateBarWidth(datasetCount);
|
2143 |
-
|
2144 |
-
return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;
|
2145 |
-
},
|
2146 |
-
calculateBaseWidth : function () {
|
2147 |
-
return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
|
2148 |
-
},
|
2149 |
-
calculateBarWidth : function (datasetCount) {
|
2150 |
-
//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
|
2151 |
-
var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);
|
2152 |
-
|
2153 |
-
return (baseWidth / datasetCount);
|
2154 |
-
}
|
2155 |
-
}
|
2156 |
-
);
|
2157 |
-
|
2158 |
-
this.datasets = [];
|
2159 |
-
|
2160 |
-
//Set up tooltip events on the chart
|
2161 |
-
if (this.options.showTooltips) {
|
2162 |
-
helpers.bindEvents(
|
2163 |
-
this, this.options.tooltipEvents, function (evt) {
|
2164 |
-
var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
|
2165 |
-
|
2166 |
-
this.eachBars(
|
2167 |
-
function (bar) {
|
2168 |
-
bar.restore(['fillColor', 'strokeColor']);
|
2169 |
-
}
|
2170 |
-
);
|
2171 |
-
helpers.each(
|
2172 |
-
activeBars, function (activeBar) {
|
2173 |
-
activeBar.fillColor = activeBar.highlightFill;
|
2174 |
-
activeBar.strokeColor = activeBar.highlightStroke;
|
2175 |
-
}
|
2176 |
-
);
|
2177 |
-
this.showTooltip(activeBars);
|
2178 |
-
}
|
2179 |
-
);
|
2180 |
-
}
|
2181 |
-
|
2182 |
-
//Declare the extension of the default point, to cater for the options passed in to the constructor
|
2183 |
-
this.BarClass = Chart.Rectangle.extend(
|
2184 |
-
{
|
2185 |
-
strokeWidth : this.options.barStrokeWidth,
|
2186 |
-
showStroke : this.options.barShowStroke,
|
2187 |
-
ctx : this.chart.ctx
|
2188 |
-
}
|
2189 |
-
);
|
2190 |
-
|
2191 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
2192 |
-
helpers.each(
|
2193 |
-
data.datasets,function (dataset,datasetIndex) {
|
2194 |
-
|
2195 |
-
var datasetObject = {
|
2196 |
-
label : dataset.label || null,
|
2197 |
-
fillColor : dataset.fillColor,
|
2198 |
-
strokeColor : dataset.strokeColor,
|
2199 |
-
bars : []
|
2200 |
-
};
|
2201 |
-
|
2202 |
-
this.datasets.push(datasetObject);
|
2203 |
-
|
2204 |
-
helpers.each(
|
2205 |
-
dataset.data,function (dataPoint,index) {
|
2206 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
2207 |
-
datasetObject.bars.push(
|
2208 |
-
new this.BarClass(
|
2209 |
-
{
|
2210 |
-
value : dataPoint,
|
2211 |
-
label : data.labels[index],
|
2212 |
-
datasetLabel: dataset.label,
|
2213 |
-
strokeColor : dataset.strokeColor,
|
2214 |
-
fillColor : dataset.fillColor,
|
2215 |
-
highlightFill : dataset.highlightFill || dataset.fillColor,
|
2216 |
-
highlightStroke : dataset.highlightStroke || dataset.strokeColor
|
2217 |
-
}
|
2218 |
-
)
|
2219 |
-
);
|
2220 |
-
},this
|
2221 |
-
);
|
2222 |
-
|
2223 |
-
},this
|
2224 |
-
);
|
2225 |
-
|
2226 |
-
this.buildScale(data.labels);
|
2227 |
-
|
2228 |
-
this.BarClass.prototype.base = this.scale.endPoint;
|
2229 |
-
|
2230 |
-
this.eachBars(
|
2231 |
-
function (bar, index, datasetIndex) {
|
2232 |
-
helpers.extend(
|
2233 |
-
bar, {
|
2234 |
-
width : this.scale.calculateBarWidth(this.datasets.length),
|
2235 |
-
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
|
2236 |
-
y: this.scale.endPoint
|
2237 |
-
}
|
2238 |
-
);
|
2239 |
-
bar.save();
|
2240 |
-
}, this
|
2241 |
-
);
|
2242 |
-
|
2243 |
-
this.render();
|
2244 |
-
},
|
2245 |
-
update : function () {
|
2246 |
-
this.scale.update();
|
2247 |
-
// Reset any highlight colours before updating.
|
2248 |
-
helpers.each(
|
2249 |
-
this.activeElements, function (activeElement) {
|
2250 |
-
activeElement.restore(['fillColor', 'strokeColor']);
|
2251 |
-
}
|
2252 |
-
);
|
2253 |
-
|
2254 |
-
this.eachBars(
|
2255 |
-
function (bar) {
|
2256 |
-
bar.save();
|
2257 |
-
}
|
2258 |
-
);
|
2259 |
-
this.render();
|
2260 |
-
},
|
2261 |
-
eachBars : function (callback) {
|
2262 |
-
helpers.each(
|
2263 |
-
this.datasets,function (dataset, datasetIndex) {
|
2264 |
-
helpers.each(dataset.bars, callback, this, datasetIndex);
|
2265 |
-
},this
|
2266 |
-
);
|
2267 |
-
},
|
2268 |
-
getBarsAtEvent : function (e) {
|
2269 |
-
var barsArray = [],
|
2270 |
-
eventPosition = helpers.getRelativePosition(e),
|
2271 |
-
datasetIterator = function (dataset) {
|
2272 |
-
barsArray.push(dataset.bars[barIndex]);
|
2273 |
-
},
|
2274 |
-
barIndex;
|
2275 |
-
|
2276 |
-
for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
|
2277 |
-
for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
|
2278 |
-
if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)) {
|
2279 |
-
helpers.each(this.datasets, datasetIterator);
|
2280 |
-
return barsArray;
|
2281 |
-
}
|
2282 |
-
}
|
2283 |
-
}
|
2284 |
-
|
2285 |
-
return barsArray;
|
2286 |
-
},
|
2287 |
-
buildScale : function (labels) {
|
2288 |
-
var self = this;
|
2289 |
-
|
2290 |
-
var dataTotal = function () {
|
2291 |
-
var values = [];
|
2292 |
-
self.eachBars(
|
2293 |
-
function (bar) {
|
2294 |
-
values.push(bar.value);
|
2295 |
-
}
|
2296 |
-
);
|
2297 |
-
return values;
|
2298 |
-
};
|
2299 |
-
|
2300 |
-
var scaleOptions = {
|
2301 |
-
templateString : this.options.scaleLabel,
|
2302 |
-
height : this.chart.height,
|
2303 |
-
width : this.chart.width,
|
2304 |
-
ctx : this.chart.ctx,
|
2305 |
-
textColor : this.options.scaleFontColor,
|
2306 |
-
fontSize : this.options.scaleFontSize,
|
2307 |
-
fontStyle : this.options.scaleFontStyle,
|
2308 |
-
fontFamily : this.options.scaleFontFamily,
|
2309 |
-
valuesCount : labels.length,
|
2310 |
-
beginAtZero : this.options.scaleBeginAtZero,
|
2311 |
-
integersOnly : this.options.scaleIntegersOnly,
|
2312 |
-
calculateYRange: function (currentHeight) {
|
2313 |
-
var updatedRanges = helpers.calculateScaleRange(
|
2314 |
-
dataTotal(),
|
2315 |
-
currentHeight,
|
2316 |
-
this.fontSize,
|
2317 |
-
this.beginAtZero,
|
2318 |
-
this.integersOnly
|
2319 |
-
);
|
2320 |
-
helpers.extend(this, updatedRanges);
|
2321 |
-
},
|
2322 |
-
xLabels : labels,
|
2323 |
-
limitXLabels: this.options.scaleLimitXLabels,
|
2324 |
-
limitXLabelsTo: this.options.scaleLimitXLabelsTo,
|
2325 |
-
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
2326 |
-
lineWidth : this.options.scaleLineWidth,
|
2327 |
-
lineColor : this.options.scaleLineColor,
|
2328 |
-
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
2329 |
-
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
2330 |
-
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
|
2331 |
-
showLabels : this.options.scaleShowLabels,
|
2332 |
-
display : this.options.showScale
|
2333 |
-
};
|
2334 |
-
|
2335 |
-
if (this.options.scaleOverride) {
|
2336 |
-
helpers.extend(
|
2337 |
-
scaleOptions, {
|
2338 |
-
calculateYRange: helpers.noop,
|
2339 |
-
steps: this.options.scaleSteps,
|
2340 |
-
stepValue: this.options.scaleStepWidth,
|
2341 |
-
min: this.options.scaleStartValue,
|
2342 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
2343 |
-
}
|
2344 |
-
);
|
2345 |
-
}
|
2346 |
-
|
2347 |
-
this.scale = new this.ScaleClass(scaleOptions);
|
2348 |
-
},
|
2349 |
-
addData : function (valuesArray,label) {
|
2350 |
-
//Map the values array for each of the datasets
|
2351 |
-
helpers.each(
|
2352 |
-
valuesArray,function (value,datasetIndex) {
|
2353 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
2354 |
-
this.datasets[datasetIndex].bars.push(
|
2355 |
-
new this.BarClass(
|
2356 |
-
{
|
2357 |
-
value : value,
|
2358 |
-
label : label,
|
2359 |
-
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
|
2360 |
-
y: this.scale.endPoint,
|
2361 |
-
width : this.scale.calculateBarWidth(this.datasets.length),
|
2362 |
-
base : this.scale.endPoint,
|
2363 |
-
strokeColor : this.datasets[datasetIndex].strokeColor,
|
2364 |
-
fillColor : this.datasets[datasetIndex].fillColor
|
2365 |
-
}
|
2366 |
-
)
|
2367 |
-
);
|
2368 |
-
},this
|
2369 |
-
);
|
2370 |
-
|
2371 |
-
this.scale.addXLabel(label);
|
2372 |
-
//Then re-render the chart.
|
2373 |
-
this.update();
|
2374 |
-
},
|
2375 |
-
removeData : function () {
|
2376 |
-
this.scale.removeXLabel();
|
2377 |
-
//Then re-render the chart.
|
2378 |
-
helpers.each(
|
2379 |
-
this.datasets,function (dataset) {
|
2380 |
-
dataset.bars.shift();
|
2381 |
-
},this
|
2382 |
-
);
|
2383 |
-
this.update();
|
2384 |
-
},
|
2385 |
-
reflow : function () {
|
2386 |
-
helpers.extend(
|
2387 |
-
this.BarClass.prototype,{
|
2388 |
-
y: this.scale.endPoint,
|
2389 |
-
base : this.scale.endPoint
|
2390 |
-
}
|
2391 |
-
);
|
2392 |
-
var newScaleProps = helpers.extend(
|
2393 |
-
{
|
2394 |
-
height : this.chart.height,
|
2395 |
-
width : this.chart.width
|
2396 |
-
}
|
2397 |
-
);
|
2398 |
-
this.scale.update(newScaleProps);
|
2399 |
-
},
|
2400 |
-
draw : function (ease) {
|
2401 |
-
var easingDecimal = ease || 1;
|
2402 |
-
this.clear();
|
2403 |
-
|
2404 |
-
var ctx = this.chart.ctx;
|
2405 |
-
|
2406 |
-
this.scale.draw(easingDecimal);
|
2407 |
-
|
2408 |
-
//Draw all the bars for each dataset
|
2409 |
-
helpers.each(
|
2410 |
-
this.datasets,function (dataset,datasetIndex) {
|
2411 |
-
helpers.each(
|
2412 |
-
dataset.bars,function (bar,index) {
|
2413 |
-
if (bar.hasValue()) {
|
2414 |
-
bar.base = this.scale.endPoint;
|
2415 |
-
//Transition then draw
|
2416 |
-
bar.transition(
|
2417 |
-
{
|
2418 |
-
x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
|
2419 |
-
y : this.scale.calculateY(bar.value),
|
2420 |
-
width : this.scale.calculateBarWidth(this.datasets.length)
|
2421 |
-
}, easingDecimal
|
2422 |
-
).draw();
|
2423 |
-
}
|
2424 |
-
},this
|
2425 |
-
);
|
2426 |
-
|
2427 |
-
},this
|
2428 |
-
);
|
2429 |
-
}
|
2430 |
}
|
2431 |
-
|
2432 |
-
|
2433 |
-
|
2434 |
-
|
2435 |
-
(
|
2436 |
-
|
2437 |
-
|
2438 |
-
|
2439 |
-
|
2440 |
-
|
2441 |
-
helpers = Chart.helpers;
|
2442 |
-
|
2443 |
-
var defaultConfig = {
|
2444 |
-
//Boolean - Whether we should show a stroke on each segment
|
2445 |
-
segmentShowStroke : true,
|
2446 |
-
|
2447 |
-
//String - The colour of each segment stroke
|
2448 |
-
segmentStrokeColor : "#fff",
|
2449 |
-
|
2450 |
-
//Number - The width of each segment stroke
|
2451 |
-
segmentStrokeWidth : 2,
|
2452 |
-
|
2453 |
-
//The percentage of the chart that we cut out of the middle.
|
2454 |
-
percentageInnerCutout : 50,
|
2455 |
-
|
2456 |
-
//Number - Amount of animation steps
|
2457 |
-
animationSteps : 100,
|
2458 |
-
|
2459 |
-
//String - Animation easing effect
|
2460 |
-
animationEasing : "easeOutBounce",
|
2461 |
-
|
2462 |
-
//Boolean - Whether we animate the rotation of the Doughnut
|
2463 |
-
animateRotate : true,
|
2464 |
-
|
2465 |
-
//Boolean - Whether we animate scaling the Doughnut from the centre
|
2466 |
-
animateScale : false,
|
2467 |
-
|
2468 |
-
//String - A legend template
|
2469 |
-
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>"
|
2470 |
-
|
2471 |
-
};
|
2472 |
-
|
2473 |
-
|
2474 |
-
Chart.Type.extend(
|
2475 |
-
{
|
2476 |
-
//Passing in a name registers this chart in the Chart namespace
|
2477 |
-
name: "Doughnut",
|
2478 |
-
//Providing a defaults will also register the deafults in the chart namespace
|
2479 |
-
defaults : defaultConfig,
|
2480 |
-
//Initialize is fired when the chart is initialized - Data is passed in as a parameter
|
2481 |
-
//Config is automatically merged by the core of Chart.js, and is available at this.options
|
2482 |
-
initialize: function (data) {
|
2483 |
-
|
2484 |
-
//Declare segments as a static property to prevent inheriting across the Chart type prototype
|
2485 |
-
this.segments = [];
|
2486 |
-
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
|
2487 |
-
|
2488 |
-
this.SegmentArc = Chart.Arc.extend(
|
2489 |
-
{
|
2490 |
-
ctx : this.chart.ctx,
|
2491 |
-
x : this.chart.width/2,
|
2492 |
-
y : this.chart.height/2
|
2493 |
-
}
|
2494 |
-
);
|
2495 |
-
|
2496 |
-
//Set up tooltip events on the chart
|
2497 |
-
if (this.options.showTooltips) {
|
2498 |
-
helpers.bindEvents(
|
2499 |
-
this, this.options.tooltipEvents, function (evt) {
|
2500 |
-
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
|
2501 |
-
|
2502 |
-
helpers.each(
|
2503 |
-
this.segments,function (segment) {
|
2504 |
-
segment.restore(["fillColor"]);
|
2505 |
-
}
|
2506 |
-
);
|
2507 |
-
helpers.each(
|
2508 |
-
activeSegments,function (activeSegment) {
|
2509 |
-
activeSegment.fillColor = activeSegment.highlightColor;
|
2510 |
-
}
|
2511 |
-
);
|
2512 |
-
this.showTooltip(activeSegments);
|
2513 |
-
}
|
2514 |
-
);
|
2515 |
-
}
|
2516 |
-
this.calculateTotal(data);
|
2517 |
-
|
2518 |
-
helpers.each(
|
2519 |
-
data,function (datapoint, index) {
|
2520 |
-
this.addData(datapoint, index, true);
|
2521 |
-
},this
|
2522 |
-
);
|
2523 |
-
|
2524 |
-
this.render();
|
2525 |
-
},
|
2526 |
-
getSegmentsAtEvent : function (e) {
|
2527 |
-
var segmentsArray = [];
|
2528 |
-
|
2529 |
-
var location = helpers.getRelativePosition(e);
|
2530 |
-
|
2531 |
-
helpers.each(
|
2532 |
-
this.segments,function (segment) {
|
2533 |
-
if (segment.inRange(location.x,location.y)) { segmentsArray.push(segment);
|
2534 |
-
}
|
2535 |
-
},this
|
2536 |
-
);
|
2537 |
-
return segmentsArray;
|
2538 |
-
},
|
2539 |
-
addData : function (segment, atIndex, silent) {
|
2540 |
-
var index = atIndex || this.segments.length;
|
2541 |
-
this.segments.splice(
|
2542 |
-
index, 0, new this.SegmentArc(
|
2543 |
-
{
|
2544 |
-
value : segment.value,
|
2545 |
-
outerRadius : (this.options.animateScale) ? 0 : this.outerRadius,
|
2546 |
-
innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,
|
2547 |
-
fillColor : segment.color,
|
2548 |
-
highlightColor : segment.highlight || segment.color,
|
2549 |
-
showStroke : this.options.segmentShowStroke,
|
2550 |
-
strokeWidth : this.options.segmentStrokeWidth,
|
2551 |
-
strokeColor : this.options.segmentStrokeColor,
|
2552 |
-
startAngle : Math.PI * 1.5,
|
2553 |
-
circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),
|
2554 |
-
label : segment.label
|
2555 |
-
}
|
2556 |
-
)
|
2557 |
-
);
|
2558 |
-
if (!silent) {
|
2559 |
-
this.reflow();
|
2560 |
-
this.update();
|
2561 |
-
}
|
2562 |
-
},
|
2563 |
-
calculateCircumference : function (value) {
|
2564 |
-
if (this.total > 0 ) {
|
2565 |
-
return (Math.PI*2)*(value / this.total);
|
2566 |
-
} else {
|
2567 |
-
return 0;
|
2568 |
-
}
|
2569 |
-
},
|
2570 |
-
calculateTotal : function (data) {
|
2571 |
-
this.total = 0;
|
2572 |
-
helpers.each(
|
2573 |
-
data,function (segment) {
|
2574 |
-
this.total += segment.value;
|
2575 |
-
},this
|
2576 |
-
);
|
2577 |
-
},
|
2578 |
-
update : function () {
|
2579 |
-
this.calculateTotal(this.segments);
|
2580 |
-
|
2581 |
-
// Reset any highlight colours before updating.
|
2582 |
-
helpers.each(
|
2583 |
-
this.activeElements, function (activeElement) {
|
2584 |
-
activeElement.restore(['fillColor']);
|
2585 |
-
}
|
2586 |
-
);
|
2587 |
-
|
2588 |
-
helpers.each(
|
2589 |
-
this.segments,function (segment) {
|
2590 |
-
segment.save();
|
2591 |
-
}
|
2592 |
-
);
|
2593 |
-
this.render();
|
2594 |
-
},
|
2595 |
-
|
2596 |
-
removeData: function (atIndex) {
|
2597 |
-
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
|
2598 |
-
this.segments.splice(indexToDelete, 1);
|
2599 |
-
this.reflow();
|
2600 |
-
this.update();
|
2601 |
-
},
|
2602 |
-
|
2603 |
-
reflow : function () {
|
2604 |
-
helpers.extend(
|
2605 |
-
this.SegmentArc.prototype,{
|
2606 |
-
x : this.chart.width/2,
|
2607 |
-
y : this.chart.height/2
|
2608 |
-
}
|
2609 |
-
);
|
2610 |
-
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
|
2611 |
-
helpers.each(
|
2612 |
-
this.segments, function (segment) {
|
2613 |
-
segment.update(
|
2614 |
-
{
|
2615 |
-
outerRadius : this.outerRadius,
|
2616 |
-
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
|
2617 |
-
}
|
2618 |
-
);
|
2619 |
-
}, this
|
2620 |
-
);
|
2621 |
-
},
|
2622 |
-
draw : function (easeDecimal) {
|
2623 |
-
var animDecimal = (easeDecimal) ? easeDecimal : 1;
|
2624 |
-
this.clear();
|
2625 |
-
helpers.each(
|
2626 |
-
this.segments,function (segment,index) {
|
2627 |
-
segment.transition(
|
2628 |
-
{
|
2629 |
-
circumference : this.calculateCircumference(segment.value),
|
2630 |
-
outerRadius : this.outerRadius,
|
2631 |
-
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
|
2632 |
-
},animDecimal
|
2633 |
-
);
|
2634 |
-
|
2635 |
-
segment.endAngle = segment.startAngle + segment.circumference;
|
2636 |
-
|
2637 |
-
segment.draw();
|
2638 |
-
if (index === 0) {
|
2639 |
-
segment.startAngle = Math.PI * 1.5;
|
2640 |
-
}
|
2641 |
-
//Check to see if it's the last segment, if not get the next and update the start angle
|
2642 |
-
if (index < this.segments.length-1) {
|
2643 |
-
this.segments[index+1].startAngle = segment.endAngle;
|
2644 |
-
}
|
2645 |
-
},this
|
2646 |
-
);
|
2647 |
-
|
2648 |
-
}
|
2649 |
}
|
2650 |
-
|
2651 |
-
|
2652 |
-
|
2653 |
-
|
2654 |
-
|
2655 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2656 |
}
|
2657 |
-
|
2658 |
-
|
2659 |
-
|
2660 |
-
|
2661 |
-
(
|
2662 |
-
|
2663 |
-
|
2664 |
-
|
2665 |
-
|
2666 |
-
|
2667 |
-
|
2668 |
-
var defaultConfig = {
|
2669 |
-
|
2670 |
-
///Boolean - Whether grid lines are shown across the chart
|
2671 |
-
scaleShowGridLines : true,
|
2672 |
-
|
2673 |
-
//String - Colour of the grid lines
|
2674 |
-
scaleGridLineColor : "rgba(0,0,0,.05)",
|
2675 |
-
|
2676 |
-
//Number - Width of the grid lines
|
2677 |
-
scaleGridLineWidth : 1,
|
2678 |
-
|
2679 |
-
//Boolean - Whether the line is curved between points
|
2680 |
-
bezierCurve : true,
|
2681 |
-
|
2682 |
-
//Number - Tension of the bezier curve between points
|
2683 |
-
bezierCurveTension : 0.4,
|
2684 |
-
|
2685 |
-
//Boolean - Whether to show a dot for each point
|
2686 |
-
pointDot : true,
|
2687 |
-
|
2688 |
-
//Number - Radius of each point dot in pixels
|
2689 |
-
pointDotRadius : 4,
|
2690 |
-
|
2691 |
-
//Number - Pixel width of point dot stroke
|
2692 |
-
pointDotStrokeWidth : 1,
|
2693 |
-
|
2694 |
-
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
2695 |
-
pointHitDetectionRadius : 0,
|
2696 |
-
|
2697 |
-
//Boolean - Whether to show a stroke for datasets
|
2698 |
-
datasetStroke : true,
|
2699 |
-
|
2700 |
-
//Number - Pixel width of dataset stroke
|
2701 |
-
datasetStrokeWidth : 2,
|
2702 |
-
|
2703 |
-
//Boolean - Whether to fill the dataset with a colour
|
2704 |
-
datasetFill : true,
|
2705 |
-
|
2706 |
-
//String - A legend template
|
2707 |
-
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>"
|
2708 |
-
|
2709 |
-
};
|
2710 |
-
|
2711 |
-
|
2712 |
-
Chart.Type.extend(
|
2713 |
-
{
|
2714 |
-
name: "Line",
|
2715 |
-
defaults : defaultConfig,
|
2716 |
-
initialize: function (data) {
|
2717 |
-
//Declare the extension of the default point, to cater for the options passed in to the constructor
|
2718 |
-
this.PointClass = Chart.Point.extend(
|
2719 |
-
{
|
2720 |
-
strokeWidth : this.options.pointDotStrokeWidth,
|
2721 |
-
radius : this.options.pointDotRadius,
|
2722 |
-
display: this.options.pointDot,
|
2723 |
-
hitDetectionRadius : this.options.pointHitDetectionRadius,
|
2724 |
-
ctx : this.chart.ctx,
|
2725 |
-
inRange : function (mouseX) {
|
2726 |
-
return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));
|
2727 |
-
}
|
2728 |
-
}
|
2729 |
-
);
|
2730 |
-
|
2731 |
-
this.datasets = [];
|
2732 |
-
|
2733 |
-
//Set up tooltip events on the chart
|
2734 |
-
if (this.options.showTooltips) {
|
2735 |
-
helpers.bindEvents(
|
2736 |
-
this, this.options.tooltipEvents, function (evt) {
|
2737 |
-
var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
|
2738 |
-
this.eachPoints(
|
2739 |
-
function (point) {
|
2740 |
-
point.restore(['fillColor', 'strokeColor']);
|
2741 |
-
}
|
2742 |
-
);
|
2743 |
-
helpers.each(
|
2744 |
-
activePoints, function (activePoint) {
|
2745 |
-
activePoint.fillColor = activePoint.highlightFill;
|
2746 |
-
activePoint.strokeColor = activePoint.highlightStroke;
|
2747 |
-
}
|
2748 |
-
);
|
2749 |
-
this.showTooltip(activePoints);
|
2750 |
-
}
|
2751 |
-
);
|
2752 |
-
}
|
2753 |
-
|
2754 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
2755 |
-
helpers.each(
|
2756 |
-
data.datasets,function (dataset) {
|
2757 |
-
|
2758 |
-
var datasetObject = {
|
2759 |
-
label : dataset.label || null,
|
2760 |
-
fillColor : dataset.fillColor,
|
2761 |
-
strokeColor : dataset.strokeColor,
|
2762 |
-
pointColor : dataset.pointColor,
|
2763 |
-
pointStrokeColor : dataset.pointStrokeColor,
|
2764 |
-
points : []
|
2765 |
-
};
|
2766 |
-
|
2767 |
-
this.datasets.push(datasetObject);
|
2768 |
-
|
2769 |
-
|
2770 |
-
helpers.each(
|
2771 |
-
dataset.data,function (dataPoint,index) {
|
2772 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
2773 |
-
datasetObject.points.push(
|
2774 |
-
new this.PointClass(
|
2775 |
-
{
|
2776 |
-
value : dataPoint,
|
2777 |
-
label : data.labels[index],
|
2778 |
-
datasetLabel: dataset.label,
|
2779 |
-
strokeColor : dataset.pointStrokeColor,
|
2780 |
-
fillColor : dataset.pointColor,
|
2781 |
-
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
2782 |
-
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
2783 |
-
}
|
2784 |
-
)
|
2785 |
-
);
|
2786 |
-
},this
|
2787 |
-
);
|
2788 |
-
|
2789 |
-
this.buildScale(data.labels);
|
2790 |
-
|
2791 |
-
|
2792 |
-
this.eachPoints(
|
2793 |
-
function (point, index) {
|
2794 |
-
helpers.extend(
|
2795 |
-
point, {
|
2796 |
-
x: this.scale.calculateX(index),
|
2797 |
-
y: this.scale.endPoint
|
2798 |
-
}
|
2799 |
-
);
|
2800 |
-
point.save();
|
2801 |
-
}, this
|
2802 |
-
);
|
2803 |
-
|
2804 |
-
},this
|
2805 |
-
);
|
2806 |
-
|
2807 |
-
|
2808 |
-
this.render();
|
2809 |
-
},
|
2810 |
-
update : function () {
|
2811 |
-
this.scale.update();
|
2812 |
-
// Reset any highlight colours before updating.
|
2813 |
-
helpers.each(
|
2814 |
-
this.activeElements, function (activeElement) {
|
2815 |
-
activeElement.restore(['fillColor', 'strokeColor']);
|
2816 |
-
}
|
2817 |
-
);
|
2818 |
-
this.eachPoints(
|
2819 |
-
function (point) {
|
2820 |
-
point.save();
|
2821 |
-
}
|
2822 |
-
);
|
2823 |
-
this.render();
|
2824 |
-
},
|
2825 |
-
eachPoints : function (callback) {
|
2826 |
-
helpers.each(
|
2827 |
-
this.datasets,function (dataset) {
|
2828 |
-
helpers.each(dataset.points,callback,this);
|
2829 |
-
},this
|
2830 |
-
);
|
2831 |
-
},
|
2832 |
-
getPointsAtEvent : function (e) {
|
2833 |
-
var pointsArray = [],
|
2834 |
-
eventPosition = helpers.getRelativePosition(e);
|
2835 |
-
helpers.each(
|
2836 |
-
this.datasets,function (dataset) {
|
2837 |
-
helpers.each(
|
2838 |
-
dataset.points,function (point) {
|
2839 |
-
if (point.inRange(eventPosition.x,eventPosition.y)) { pointsArray.push(point);
|
2840 |
-
}
|
2841 |
-
}
|
2842 |
-
);
|
2843 |
-
},this
|
2844 |
-
);
|
2845 |
-
return pointsArray;
|
2846 |
-
},
|
2847 |
-
buildScale : function (labels) {
|
2848 |
-
var self = this;
|
2849 |
-
|
2850 |
-
var dataTotal = function () {
|
2851 |
-
var values = [];
|
2852 |
-
self.eachPoints(
|
2853 |
-
function (point) {
|
2854 |
-
values.push(point.value);
|
2855 |
-
}
|
2856 |
-
);
|
2857 |
-
|
2858 |
-
return values;
|
2859 |
-
};
|
2860 |
-
|
2861 |
-
var scaleOptions = {
|
2862 |
-
templateString : this.options.scaleLabel,
|
2863 |
-
height : this.chart.height,
|
2864 |
-
width : this.chart.width,
|
2865 |
-
ctx : this.chart.ctx,
|
2866 |
-
textColor : this.options.scaleFontColor,
|
2867 |
-
fontSize : this.options.scaleFontSize,
|
2868 |
-
fontStyle : this.options.scaleFontStyle,
|
2869 |
-
fontFamily : this.options.scaleFontFamily,
|
2870 |
-
valuesCount : labels.length,
|
2871 |
-
beginAtZero : this.options.scaleBeginAtZero,
|
2872 |
-
integersOnly : this.options.scaleIntegersOnly,
|
2873 |
-
calculateYRange : function (currentHeight) {
|
2874 |
-
var updatedRanges = helpers.calculateScaleRange(
|
2875 |
-
dataTotal(),
|
2876 |
-
currentHeight,
|
2877 |
-
this.fontSize,
|
2878 |
-
this.beginAtZero,
|
2879 |
-
this.integersOnly
|
2880 |
-
);
|
2881 |
-
helpers.extend(this, updatedRanges);
|
2882 |
-
},
|
2883 |
-
xLabels : labels,
|
2884 |
-
limitXLabels: this.options.scaleLimitXLabels,
|
2885 |
-
limitXLabelsTo: this.options.scaleLimitXLabelsTo,
|
2886 |
-
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
|
2887 |
-
lineWidth : this.options.scaleLineWidth,
|
2888 |
-
lineColor : this.options.scaleLineColor,
|
2889 |
-
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
|
2890 |
-
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
|
2891 |
-
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
|
2892 |
-
showLabels : this.options.scaleShowLabels,
|
2893 |
-
display : this.options.showScale
|
2894 |
-
};
|
2895 |
-
|
2896 |
-
if (this.options.scaleOverride) {
|
2897 |
-
helpers.extend(
|
2898 |
-
scaleOptions, {
|
2899 |
-
calculateYRange: helpers.noop,
|
2900 |
-
steps: this.options.scaleSteps,
|
2901 |
-
stepValue: this.options.scaleStepWidth,
|
2902 |
-
min: this.options.scaleStartValue,
|
2903 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
2904 |
-
}
|
2905 |
-
);
|
2906 |
-
}
|
2907 |
-
|
2908 |
-
|
2909 |
-
this.scale = new Chart.Scale(scaleOptions);
|
2910 |
-
},
|
2911 |
-
addData : function (valuesArray,label) {
|
2912 |
-
//Map the values array for each of the datasets
|
2913 |
-
|
2914 |
-
helpers.each(
|
2915 |
-
valuesArray,function (value,datasetIndex) {
|
2916 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
2917 |
-
this.datasets[datasetIndex].points.push(
|
2918 |
-
new this.PointClass(
|
2919 |
-
{
|
2920 |
-
value : value,
|
2921 |
-
label : label,
|
2922 |
-
x: this.scale.calculateX(this.scale.valuesCount+1),
|
2923 |
-
y: this.scale.endPoint,
|
2924 |
-
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
|
2925 |
-
fillColor : this.datasets[datasetIndex].pointColor
|
2926 |
-
}
|
2927 |
-
)
|
2928 |
-
);
|
2929 |
-
},this
|
2930 |
-
);
|
2931 |
-
|
2932 |
-
this.scale.addXLabel(label);
|
2933 |
-
//Then re-render the chart.
|
2934 |
-
this.update();
|
2935 |
-
},
|
2936 |
-
removeData : function () {
|
2937 |
-
this.scale.removeXLabel();
|
2938 |
-
//Then re-render the chart.
|
2939 |
-
helpers.each(
|
2940 |
-
this.datasets,function (dataset) {
|
2941 |
-
dataset.points.shift();
|
2942 |
-
},this
|
2943 |
-
);
|
2944 |
-
this.update();
|
2945 |
-
},
|
2946 |
-
reflow : function () {
|
2947 |
-
var newScaleProps = helpers.extend(
|
2948 |
-
{
|
2949 |
-
height : this.chart.height,
|
2950 |
-
width : this.chart.width
|
2951 |
-
}
|
2952 |
-
);
|
2953 |
-
this.scale.update(newScaleProps);
|
2954 |
-
},
|
2955 |
-
draw : function (ease) {
|
2956 |
-
var easingDecimal = ease || 1;
|
2957 |
-
this.clear();
|
2958 |
-
|
2959 |
-
var ctx = this.chart.ctx;
|
2960 |
-
|
2961 |
-
// Some helper methods for getting the next/prev points
|
2962 |
-
var hasValue = function (item) {
|
2963 |
-
return item.value !== null;
|
2964 |
-
},
|
2965 |
-
nextPoint = function (point, collection, index) {
|
2966 |
-
return helpers.findNextWhere(collection, hasValue, index) || point;
|
2967 |
-
},
|
2968 |
-
previousPoint = function (point, collection, index) {
|
2969 |
-
return helpers.findPreviousWhere(collection, hasValue, index) || point;
|
2970 |
-
};
|
2971 |
-
|
2972 |
-
this.scale.draw(easingDecimal);
|
2973 |
-
|
2974 |
-
|
2975 |
-
helpers.each(
|
2976 |
-
this.datasets,function (dataset) {
|
2977 |
-
var pointsWithValues = helpers.where(dataset.points, hasValue);
|
2978 |
-
|
2979 |
-
//Transition each point first so that the line and point drawing isn't out of sync
|
2980 |
-
//We can use this extra loop to calculate the control points of this dataset also in this loop
|
2981 |
-
|
2982 |
-
helpers.each(
|
2983 |
-
dataset.points, function (point, index) {
|
2984 |
-
if (point.hasValue()) {
|
2985 |
-
point.transition(
|
2986 |
-
{
|
2987 |
-
y : this.scale.calculateY(point.value),
|
2988 |
-
x : this.scale.calculateX(index)
|
2989 |
-
}, easingDecimal
|
2990 |
-
);
|
2991 |
-
}
|
2992 |
-
},this
|
2993 |
-
);
|
2994 |
-
|
2995 |
-
|
2996 |
-
// Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point
|
2997 |
-
// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed
|
2998 |
-
if (this.options.bezierCurve) {
|
2999 |
-
helpers.each(
|
3000 |
-
pointsWithValues, function (point, index) {
|
3001 |
-
var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;
|
3002 |
-
point.controlPoints = helpers.splineCurve(
|
3003 |
-
previousPoint(point, pointsWithValues, index),
|
3004 |
-
point,
|
3005 |
-
nextPoint(point, pointsWithValues, index),
|
3006 |
-
tension
|
3007 |
-
);
|
3008 |
-
|
3009 |
-
// Prevent the bezier going outside of the bounds of the graph
|
3010 |
-
|
3011 |
-
// Cap puter bezier handles to the upper/lower scale bounds
|
3012 |
-
if (point.controlPoints.outer.y > this.scale.endPoint) {
|
3013 |
-
point.controlPoints.outer.y = this.scale.endPoint;
|
3014 |
-
}
|
3015 |
-
else if (point.controlPoints.outer.y < this.scale.startPoint) {
|
3016 |
-
point.controlPoints.outer.y = this.scale.startPoint;
|
3017 |
-
}
|
3018 |
-
|
3019 |
-
// Cap inner bezier handles to the upper/lower scale bounds
|
3020 |
-
if (point.controlPoints.inner.y > this.scale.endPoint) {
|
3021 |
-
point.controlPoints.inner.y = this.scale.endPoint;
|
3022 |
-
}
|
3023 |
-
else if (point.controlPoints.inner.y < this.scale.startPoint) {
|
3024 |
-
point.controlPoints.inner.y = this.scale.startPoint;
|
3025 |
-
}
|
3026 |
-
},this
|
3027 |
-
);
|
3028 |
-
}
|
3029 |
-
|
3030 |
-
|
3031 |
-
//Draw the line between all the points
|
3032 |
-
ctx.lineWidth = this.options.datasetStrokeWidth;
|
3033 |
-
ctx.strokeStyle = dataset.strokeColor;
|
3034 |
-
ctx.beginPath();
|
3035 |
-
|
3036 |
-
helpers.each(
|
3037 |
-
pointsWithValues, function (point, index) {
|
3038 |
-
if (index === 0) {
|
3039 |
-
ctx.moveTo(point.x, point.y);
|
3040 |
-
}
|
3041 |
-
else{
|
3042 |
-
if(this.options.bezierCurve) {
|
3043 |
-
var previous = previousPoint(point, pointsWithValues, index);
|
3044 |
-
|
3045 |
-
ctx.bezierCurveTo(
|
3046 |
-
previous.controlPoints.outer.x,
|
3047 |
-
previous.controlPoints.outer.y,
|
3048 |
-
point.controlPoints.inner.x,
|
3049 |
-
point.controlPoints.inner.y,
|
3050 |
-
point.x,
|
3051 |
-
point.y
|
3052 |
-
);
|
3053 |
-
}
|
3054 |
-
else{
|
3055 |
-
ctx.lineTo(point.x,point.y);
|
3056 |
-
}
|
3057 |
-
}
|
3058 |
-
}, this
|
3059 |
-
);
|
3060 |
-
|
3061 |
-
ctx.stroke();
|
3062 |
-
|
3063 |
-
if (this.options.datasetFill && pointsWithValues.length > 0) {
|
3064 |
-
//Round off the line by going to the base of the chart, back to the start, then fill.
|
3065 |
-
ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);
|
3066 |
-
ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);
|
3067 |
-
ctx.fillStyle = dataset.fillColor;
|
3068 |
-
ctx.closePath();
|
3069 |
-
ctx.fill();
|
3070 |
-
}
|
3071 |
-
|
3072 |
-
//Now draw the points over the line
|
3073 |
-
//A little inefficient double looping, but better than the line
|
3074 |
-
//lagging behind the point positions
|
3075 |
-
helpers.each(
|
3076 |
-
pointsWithValues,function (point) {
|
3077 |
-
point.draw();
|
3078 |
-
}
|
3079 |
-
);
|
3080 |
-
},this
|
3081 |
-
);
|
3082 |
-
}
|
3083 |
}
|
3084 |
-
|
3085 |
-
|
3086 |
-
|
3087 |
-
}
|
3088 |
-
|
3089 |
-
|
3090 |
-
|
3091 |
-
|
3092 |
-
|
3093 |
-
|
3094 |
-
|
3095 |
-
|
3096 |
-
|
3097 |
-
|
3098 |
-
|
3099 |
-
|
3100 |
-
|
3101 |
-
|
3102 |
-
|
3103 |
-
|
3104 |
-
|
3105 |
-
|
3106 |
-
|
3107 |
-
|
3108 |
-
|
3109 |
-
|
3110 |
-
|
3111 |
-
|
3112 |
-
|
3113 |
-
|
3114 |
-
|
3115 |
-
|
3116 |
-
|
3117 |
-
|
3118 |
-
|
3119 |
-
|
3120 |
-
|
3121 |
-
|
3122 |
-
|
3123 |
-
|
3124 |
-
|
3125 |
-
|
3126 |
-
|
3127 |
-
|
3128 |
-
|
3129 |
-
|
3130 |
-
|
3131 |
-
|
3132 |
-
|
3133 |
-
|
3134 |
-
|
3135 |
-
|
3136 |
-
|
3137 |
-
|
3138 |
-
|
3139 |
-
|
3140 |
-
|
3141 |
-
|
3142 |
-
|
3143 |
-
|
3144 |
-
|
3145 |
-
|
3146 |
-
|
3147 |
-
|
3148 |
-
|
3149 |
-
|
3150 |
-
|
3151 |
-
|
3152 |
-
|
3153 |
-
{
|
3154 |
-
showStroke : this.options.segmentShowStroke,
|
3155 |
-
strokeWidth : this.options.segmentStrokeWidth,
|
3156 |
-
strokeColor : this.options.segmentStrokeColor,
|
3157 |
-
ctx : this.chart.ctx,
|
3158 |
-
innerRadius : 0,
|
3159 |
-
x : this.chart.width/2,
|
3160 |
-
y : this.chart.height/2
|
3161 |
-
}
|
3162 |
-
);
|
3163 |
-
this.scale = new Chart.RadialScale(
|
3164 |
-
{
|
3165 |
-
display: this.options.showScale,
|
3166 |
-
fontStyle: this.options.scaleFontStyle,
|
3167 |
-
fontSize: this.options.scaleFontSize,
|
3168 |
-
fontFamily: this.options.scaleFontFamily,
|
3169 |
-
fontColor: this.options.scaleFontColor,
|
3170 |
-
showLabels: this.options.scaleShowLabels,
|
3171 |
-
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
|
3172 |
-
backdropColor: this.options.scaleBackdropColor,
|
3173 |
-
backdropPaddingY : this.options.scaleBackdropPaddingY,
|
3174 |
-
backdropPaddingX: this.options.scaleBackdropPaddingX,
|
3175 |
-
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
|
3176 |
-
lineColor: this.options.scaleLineColor,
|
3177 |
-
lineArc: true,
|
3178 |
-
width: this.chart.width,
|
3179 |
-
height: this.chart.height,
|
3180 |
-
xCenter: this.chart.width/2,
|
3181 |
-
yCenter: this.chart.height/2,
|
3182 |
-
ctx : this.chart.ctx,
|
3183 |
-
templateString: this.options.scaleLabel,
|
3184 |
-
valuesCount: data.length
|
3185 |
-
}
|
3186 |
-
);
|
3187 |
-
|
3188 |
-
this.updateScaleRange(data);
|
3189 |
-
|
3190 |
-
this.scale.update();
|
3191 |
-
|
3192 |
-
helpers.each(
|
3193 |
-
data,function (segment,index) {
|
3194 |
-
this.addData(segment,index,true);
|
3195 |
-
},this
|
3196 |
-
);
|
3197 |
-
|
3198 |
-
//Set up tooltip events on the chart
|
3199 |
-
if (this.options.showTooltips) {
|
3200 |
-
helpers.bindEvents(
|
3201 |
-
this, this.options.tooltipEvents, function (evt) {
|
3202 |
-
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
|
3203 |
-
helpers.each(
|
3204 |
-
this.segments,function (segment) {
|
3205 |
-
segment.restore(["fillColor"]);
|
3206 |
-
}
|
3207 |
-
);
|
3208 |
-
helpers.each(
|
3209 |
-
activeSegments,function (activeSegment) {
|
3210 |
-
activeSegment.fillColor = activeSegment.highlightColor;
|
3211 |
-
}
|
3212 |
-
);
|
3213 |
-
this.showTooltip(activeSegments);
|
3214 |
-
}
|
3215 |
-
);
|
3216 |
-
}
|
3217 |
-
|
3218 |
-
this.render();
|
3219 |
-
},
|
3220 |
-
getSegmentsAtEvent : function (e) {
|
3221 |
-
var segmentsArray = [];
|
3222 |
-
|
3223 |
-
var location = helpers.getRelativePosition(e);
|
3224 |
-
|
3225 |
-
helpers.each(
|
3226 |
-
this.segments,function (segment) {
|
3227 |
-
if (segment.inRange(location.x,location.y)) { segmentsArray.push(segment);
|
3228 |
-
}
|
3229 |
-
},this
|
3230 |
-
);
|
3231 |
-
return segmentsArray;
|
3232 |
-
},
|
3233 |
-
addData : function (segment, atIndex, silent) {
|
3234 |
-
var index = atIndex || this.segments.length;
|
3235 |
-
|
3236 |
-
this.segments.splice(
|
3237 |
-
index, 0, new this.SegmentArc(
|
3238 |
-
{
|
3239 |
-
fillColor: segment.color,
|
3240 |
-
highlightColor: segment.highlight || segment.color,
|
3241 |
-
label: segment.label,
|
3242 |
-
value: segment.value,
|
3243 |
-
outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
|
3244 |
-
circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
|
3245 |
-
startAngle: Math.PI * 1.5
|
3246 |
-
}
|
3247 |
-
)
|
3248 |
-
);
|
3249 |
-
if (!silent) {
|
3250 |
-
this.reflow();
|
3251 |
-
this.update();
|
3252 |
-
}
|
3253 |
-
},
|
3254 |
-
removeData: function (atIndex) {
|
3255 |
-
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
|
3256 |
-
this.segments.splice(indexToDelete, 1);
|
3257 |
-
this.reflow();
|
3258 |
-
this.update();
|
3259 |
-
},
|
3260 |
-
calculateTotal: function (data) {
|
3261 |
-
this.total = 0;
|
3262 |
-
helpers.each(
|
3263 |
-
data,function (segment) {
|
3264 |
-
this.total += segment.value;
|
3265 |
-
},this
|
3266 |
-
);
|
3267 |
-
this.scale.valuesCount = this.segments.length;
|
3268 |
-
},
|
3269 |
-
updateScaleRange: function (datapoints) {
|
3270 |
-
var valuesArray = [];
|
3271 |
-
helpers.each(
|
3272 |
-
datapoints,function (segment) {
|
3273 |
-
valuesArray.push(segment.value);
|
3274 |
-
}
|
3275 |
-
);
|
3276 |
-
|
3277 |
-
var scaleSizes = (this.options.scaleOverride) ?
|
3278 |
-
{
|
3279 |
-
steps: this.options.scaleSteps,
|
3280 |
-
stepValue: this.options.scaleStepWidth,
|
3281 |
-
min: this.options.scaleStartValue,
|
3282 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
3283 |
-
} :
|
3284 |
-
helpers.calculateScaleRange(
|
3285 |
-
valuesArray,
|
3286 |
-
helpers.min([this.chart.width, this.chart.height])/2,
|
3287 |
-
this.options.scaleFontSize,
|
3288 |
-
this.options.scaleBeginAtZero,
|
3289 |
-
this.options.scaleIntegersOnly
|
3290 |
-
);
|
3291 |
-
|
3292 |
-
helpers.extend(
|
3293 |
-
this.scale,
|
3294 |
-
scaleSizes,
|
3295 |
-
{
|
3296 |
-
size: helpers.min([this.chart.width, this.chart.height]),
|
3297 |
-
xCenter: this.chart.width/2,
|
3298 |
-
yCenter: this.chart.height/2
|
3299 |
-
}
|
3300 |
-
);
|
3301 |
-
|
3302 |
-
},
|
3303 |
-
update : function () {
|
3304 |
-
this.calculateTotal(this.segments);
|
3305 |
-
|
3306 |
-
helpers.each(
|
3307 |
-
this.segments,function (segment) {
|
3308 |
-
segment.save();
|
3309 |
-
}
|
3310 |
-
);
|
3311 |
-
this.render();
|
3312 |
-
},
|
3313 |
-
reflow : function () {
|
3314 |
-
helpers.extend(
|
3315 |
-
this.SegmentArc.prototype,{
|
3316 |
-
x : this.chart.width/2,
|
3317 |
-
y : this.chart.height/2
|
3318 |
-
}
|
3319 |
-
);
|
3320 |
-
this.updateScaleRange(this.segments);
|
3321 |
-
this.scale.update();
|
3322 |
-
|
3323 |
-
helpers.extend(
|
3324 |
-
this.scale,{
|
3325 |
-
xCenter: this.chart.width/2,
|
3326 |
-
yCenter: this.chart.height/2
|
3327 |
-
}
|
3328 |
-
);
|
3329 |
-
|
3330 |
-
helpers.each(
|
3331 |
-
this.segments, function (segment) {
|
3332 |
-
segment.update(
|
3333 |
-
{
|
3334 |
-
outerRadius : this.scale.calculateCenterOffset(segment.value)
|
3335 |
-
}
|
3336 |
-
);
|
3337 |
-
}, this
|
3338 |
-
);
|
3339 |
-
|
3340 |
-
},
|
3341 |
-
draw : function (ease) {
|
3342 |
-
var easingDecimal = ease || 1;
|
3343 |
-
//Clear & draw the canvas
|
3344 |
-
this.clear();
|
3345 |
-
helpers.each(
|
3346 |
-
this.segments,function (segment, index) {
|
3347 |
-
segment.transition(
|
3348 |
-
{
|
3349 |
-
circumference : this.scale.getCircumference(),
|
3350 |
-
outerRadius : this.scale.calculateCenterOffset(segment.value)
|
3351 |
-
},easingDecimal
|
3352 |
-
);
|
3353 |
-
|
3354 |
-
segment.endAngle = segment.startAngle + segment.circumference;
|
3355 |
-
|
3356 |
-
// If we've removed the first segment we need to set the first one to
|
3357 |
-
// start at the top.
|
3358 |
-
if (index === 0) {
|
3359 |
-
segment.startAngle = Math.PI * 1.5;
|
3360 |
-
}
|
3361 |
-
|
3362 |
-
//Check to see if it's the last segment, if not get the next and update the start angle
|
3363 |
-
if (index < this.segments.length - 1) {
|
3364 |
-
this.segments[index+1].startAngle = segment.endAngle;
|
3365 |
-
}
|
3366 |
-
segment.draw();
|
3367 |
-
}, this
|
3368 |
-
);
|
3369 |
-
this.scale.draw();
|
3370 |
-
}
|
3371 |
}
|
3372 |
-
|
3373 |
-
|
3374 |
-
}
|
3375 |
-
|
3376 |
-
|
3377 |
-
|
3378 |
-
|
3379 |
-
|
3380 |
-
|
3381 |
-
|
3382 |
-
|
3383 |
-
|
3384 |
-
Chart.Type.extend(
|
3385 |
-
{
|
3386 |
-
name: "Radar",
|
3387 |
-
defaults:{
|
3388 |
-
//Boolean - Whether to show lines for each scale point
|
3389 |
-
scaleShowLine : true,
|
3390 |
-
|
3391 |
-
//Boolean - Whether we show the angle lines out of the radar
|
3392 |
-
angleShowLineOut : true,
|
3393 |
-
|
3394 |
-
//Boolean - Whether to show labels on the scale
|
3395 |
-
scaleShowLabels : false,
|
3396 |
-
|
3397 |
-
// Boolean - Whether the scale should begin at zero
|
3398 |
-
scaleBeginAtZero : true,
|
3399 |
-
|
3400 |
-
//String - Colour of the angle line
|
3401 |
-
angleLineColor : "rgba(0,0,0,.1)",
|
3402 |
-
|
3403 |
-
//Number - Pixel width of the angle line
|
3404 |
-
angleLineWidth : 1,
|
3405 |
-
|
3406 |
-
//String - Point label font declaration
|
3407 |
-
pointLabelFontFamily : "'Arial'",
|
3408 |
-
|
3409 |
-
//String - Point label font weight
|
3410 |
-
pointLabelFontStyle : "normal",
|
3411 |
-
|
3412 |
-
//Number - Point label font size in pixels
|
3413 |
-
pointLabelFontSize : 10,
|
3414 |
-
|
3415 |
-
//String - Point label font colour
|
3416 |
-
pointLabelFontColor : "#666",
|
3417 |
-
|
3418 |
-
//Boolean - Whether to show a dot for each point
|
3419 |
-
pointDot : true,
|
3420 |
-
|
3421 |
-
//Number - Radius of each point dot in pixels
|
3422 |
-
pointDotRadius : 3,
|
3423 |
-
|
3424 |
-
//Number - Pixel width of point dot stroke
|
3425 |
-
pointDotStrokeWidth : 1,
|
3426 |
-
|
3427 |
-
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
3428 |
-
pointHitDetectionRadius : 20,
|
3429 |
-
|
3430 |
-
//Boolean - Whether to show a stroke for datasets
|
3431 |
-
datasetStroke : true,
|
3432 |
-
|
3433 |
-
//Number - Pixel width of dataset stroke
|
3434 |
-
datasetStrokeWidth : 2,
|
3435 |
-
|
3436 |
-
//Boolean - Whether to fill the dataset with a colour
|
3437 |
-
datasetFill : true,
|
3438 |
-
|
3439 |
-
//String - A legend template
|
3440 |
-
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>"
|
3441 |
-
|
3442 |
-
},
|
3443 |
-
|
3444 |
-
initialize: function (data) {
|
3445 |
-
this.PointClass = Chart.Point.extend(
|
3446 |
-
{
|
3447 |
-
strokeWidth : this.options.pointDotStrokeWidth,
|
3448 |
-
radius : this.options.pointDotRadius,
|
3449 |
-
display: this.options.pointDot,
|
3450 |
-
hitDetectionRadius : this.options.pointHitDetectionRadius,
|
3451 |
-
ctx : this.chart.ctx
|
3452 |
-
}
|
3453 |
-
);
|
3454 |
-
|
3455 |
-
this.datasets = [];
|
3456 |
-
|
3457 |
-
this.buildScale(data);
|
3458 |
-
|
3459 |
-
//Set up tooltip events on the chart
|
3460 |
-
if (this.options.showTooltips) {
|
3461 |
-
helpers.bindEvents(
|
3462 |
-
this, this.options.tooltipEvents, function (evt) {
|
3463 |
-
var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
|
3464 |
-
|
3465 |
-
this.eachPoints(
|
3466 |
-
function (point) {
|
3467 |
-
point.restore(['fillColor', 'strokeColor']);
|
3468 |
-
}
|
3469 |
-
);
|
3470 |
-
helpers.each(
|
3471 |
-
activePointsCollection, function (activePoint) {
|
3472 |
-
activePoint.fillColor = activePoint.highlightFill;
|
3473 |
-
activePoint.strokeColor = activePoint.highlightStroke;
|
3474 |
-
}
|
3475 |
-
);
|
3476 |
-
|
3477 |
-
this.showTooltip(activePointsCollection);
|
3478 |
-
}
|
3479 |
-
);
|
3480 |
-
}
|
3481 |
-
|
3482 |
-
//Iterate through each of the datasets, and build this into a property of the chart
|
3483 |
-
helpers.each(
|
3484 |
-
data.datasets,function (dataset) {
|
3485 |
-
|
3486 |
-
var datasetObject = {
|
3487 |
-
label: dataset.label || null,
|
3488 |
-
fillColor : dataset.fillColor,
|
3489 |
-
strokeColor : dataset.strokeColor,
|
3490 |
-
pointColor : dataset.pointColor,
|
3491 |
-
pointStrokeColor : dataset.pointStrokeColor,
|
3492 |
-
points : []
|
3493 |
-
};
|
3494 |
-
|
3495 |
-
this.datasets.push(datasetObject);
|
3496 |
-
|
3497 |
-
helpers.each(
|
3498 |
-
dataset.data,function (dataPoint,index) {
|
3499 |
-
//Add a new point for each piece of data, passing any required data to draw.
|
3500 |
-
var pointPosition;
|
3501 |
-
if (!this.scale.animation) {
|
3502 |
-
pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));
|
3503 |
-
}
|
3504 |
-
datasetObject.points.push(
|
3505 |
-
new this.PointClass(
|
3506 |
-
{
|
3507 |
-
value : dataPoint,
|
3508 |
-
label : data.labels[index],
|
3509 |
-
datasetLabel: dataset.label,
|
3510 |
-
x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
|
3511 |
-
y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
|
3512 |
-
strokeColor : dataset.pointStrokeColor,
|
3513 |
-
fillColor : dataset.pointColor,
|
3514 |
-
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
|
3515 |
-
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
|
3516 |
-
}
|
3517 |
-
)
|
3518 |
-
);
|
3519 |
-
},this
|
3520 |
-
);
|
3521 |
-
|
3522 |
-
},this
|
3523 |
-
);
|
3524 |
-
|
3525 |
-
this.render();
|
3526 |
-
},
|
3527 |
-
eachPoints : function (callback) {
|
3528 |
-
helpers.each(
|
3529 |
-
this.datasets,function (dataset) {
|
3530 |
-
helpers.each(dataset.points,callback,this);
|
3531 |
-
},this
|
3532 |
-
);
|
3533 |
-
},
|
3534 |
-
|
3535 |
-
getPointsAtEvent : function (evt) {
|
3536 |
-
var mousePosition = helpers.getRelativePosition(evt),
|
3537 |
-
fromCenter = helpers.getAngleFromPoint(
|
3538 |
-
{
|
3539 |
-
x: this.scale.xCenter,
|
3540 |
-
y: this.scale.yCenter
|
3541 |
-
}, mousePosition
|
3542 |
-
);
|
3543 |
-
|
3544 |
-
var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,
|
3545 |
-
pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),
|
3546 |
-
activePointsCollection = [];
|
3547 |
-
|
3548 |
-
// If we're at the top, make the pointIndex 0 to get the first of the array.
|
3549 |
-
if (pointIndex >= this.scale.valuesCount || pointIndex < 0) {
|
3550 |
-
pointIndex = 0;
|
3551 |
-
}
|
3552 |
-
|
3553 |
-
if (fromCenter.distance <= this.scale.drawingArea) {
|
3554 |
-
helpers.each(
|
3555 |
-
this.datasets, function (dataset) {
|
3556 |
-
activePointsCollection.push(dataset.points[pointIndex]);
|
3557 |
-
}
|
3558 |
-
);
|
3559 |
-
}
|
3560 |
-
|
3561 |
-
return activePointsCollection;
|
3562 |
-
},
|
3563 |
-
|
3564 |
-
buildScale : function (data) {
|
3565 |
-
this.scale = new Chart.RadialScale(
|
3566 |
-
{
|
3567 |
-
display: this.options.showScale,
|
3568 |
-
fontStyle: this.options.scaleFontStyle,
|
3569 |
-
fontSize: this.options.scaleFontSize,
|
3570 |
-
fontFamily: this.options.scaleFontFamily,
|
3571 |
-
fontColor: this.options.scaleFontColor,
|
3572 |
-
showLabels: this.options.scaleShowLabels,
|
3573 |
-
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
|
3574 |
-
backdropColor: this.options.scaleBackdropColor,
|
3575 |
-
backdropPaddingY : this.options.scaleBackdropPaddingY,
|
3576 |
-
backdropPaddingX: this.options.scaleBackdropPaddingX,
|
3577 |
-
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
|
3578 |
-
lineColor: this.options.scaleLineColor,
|
3579 |
-
angleLineColor : this.options.angleLineColor,
|
3580 |
-
angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,
|
3581 |
-
// Point labels at the edge of each line
|
3582 |
-
pointLabelFontColor : this.options.pointLabelFontColor,
|
3583 |
-
pointLabelFontSize : this.options.pointLabelFontSize,
|
3584 |
-
pointLabelFontFamily : this.options.pointLabelFontFamily,
|
3585 |
-
pointLabelFontStyle : this.options.pointLabelFontStyle,
|
3586 |
-
height : this.chart.height,
|
3587 |
-
width: this.chart.width,
|
3588 |
-
xCenter: this.chart.width/2,
|
3589 |
-
yCenter: this.chart.height/2,
|
3590 |
-
ctx : this.chart.ctx,
|
3591 |
-
templateString: this.options.scaleLabel,
|
3592 |
-
labels: data.labels,
|
3593 |
-
valuesCount: data.datasets[0].data.length
|
3594 |
-
}
|
3595 |
-
);
|
3596 |
-
|
3597 |
-
this.scale.setScaleSize();
|
3598 |
-
this.updateScaleRange(data.datasets);
|
3599 |
-
this.scale.buildYLabels();
|
3600 |
-
},
|
3601 |
-
updateScaleRange: function (datasets) {
|
3602 |
-
var valuesArray = (function () {
|
3603 |
-
var totalDataArray = [];
|
3604 |
-
helpers.each(
|
3605 |
-
datasets,function (dataset) {
|
3606 |
-
if (dataset.data) {
|
3607 |
-
totalDataArray = totalDataArray.concat(dataset.data);
|
3608 |
-
}
|
3609 |
-
else {
|
3610 |
-
helpers.each(
|
3611 |
-
dataset.points, function (point) {
|
3612 |
-
totalDataArray.push(point.value);
|
3613 |
-
}
|
3614 |
-
);
|
3615 |
-
}
|
3616 |
-
}
|
3617 |
-
);
|
3618 |
-
return totalDataArray;
|
3619 |
-
})();
|
3620 |
-
|
3621 |
-
|
3622 |
-
var scaleSizes = (this.options.scaleOverride) ?
|
3623 |
-
{
|
3624 |
-
steps: this.options.scaleSteps,
|
3625 |
-
stepValue: this.options.scaleStepWidth,
|
3626 |
-
min: this.options.scaleStartValue,
|
3627 |
-
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
3628 |
-
} :
|
3629 |
-
helpers.calculateScaleRange(
|
3630 |
-
valuesArray,
|
3631 |
-
helpers.min([this.chart.width, this.chart.height])/2,
|
3632 |
-
this.options.scaleFontSize,
|
3633 |
-
this.options.scaleBeginAtZero,
|
3634 |
-
this.options.scaleIntegersOnly
|
3635 |
-
);
|
3636 |
-
|
3637 |
-
helpers.extend(
|
3638 |
-
this.scale,
|
3639 |
-
scaleSizes
|
3640 |
-
);
|
3641 |
-
|
3642 |
-
},
|
3643 |
-
addData : function (valuesArray,label) {
|
3644 |
-
//Map the values array for each of the datasets
|
3645 |
-
this.scale.valuesCount++;
|
3646 |
-
helpers.each(
|
3647 |
-
valuesArray,function (value,datasetIndex) {
|
3648 |
-
var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));
|
3649 |
-
this.datasets[datasetIndex].points.push(
|
3650 |
-
new this.PointClass(
|
3651 |
-
{
|
3652 |
-
value : value,
|
3653 |
-
label : label,
|
3654 |
-
x: pointPosition.x,
|
3655 |
-
y: pointPosition.y,
|
3656 |
-
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
|
3657 |
-
fillColor : this.datasets[datasetIndex].pointColor
|
3658 |
-
}
|
3659 |
-
)
|
3660 |
-
);
|
3661 |
-
},this
|
3662 |
-
);
|
3663 |
-
|
3664 |
-
this.scale.labels.push(label);
|
3665 |
-
|
3666 |
-
this.reflow();
|
3667 |
-
|
3668 |
-
this.update();
|
3669 |
-
},
|
3670 |
-
removeData : function () {
|
3671 |
-
this.scale.valuesCount--;
|
3672 |
-
this.scale.labels.shift();
|
3673 |
-
helpers.each(
|
3674 |
-
this.datasets,function (dataset) {
|
3675 |
-
dataset.points.shift();
|
3676 |
-
},this
|
3677 |
-
);
|
3678 |
-
this.reflow();
|
3679 |
-
this.update();
|
3680 |
-
},
|
3681 |
-
update : function () {
|
3682 |
-
this.eachPoints(
|
3683 |
-
function (point) {
|
3684 |
-
point.save();
|
3685 |
-
}
|
3686 |
-
);
|
3687 |
-
this.reflow();
|
3688 |
-
this.render();
|
3689 |
-
},
|
3690 |
-
reflow: function () {
|
3691 |
-
helpers.extend(
|
3692 |
-
this.scale, {
|
3693 |
-
width : this.chart.width,
|
3694 |
-
height: this.chart.height,
|
3695 |
-
size : helpers.min([this.chart.width, this.chart.height]),
|
3696 |
-
xCenter: this.chart.width/2,
|
3697 |
-
yCenter: this.chart.height/2
|
3698 |
-
}
|
3699 |
-
);
|
3700 |
-
this.updateScaleRange(this.datasets);
|
3701 |
-
this.scale.setScaleSize();
|
3702 |
-
this.scale.buildYLabels();
|
3703 |
-
},
|
3704 |
-
draw : function (ease) {
|
3705 |
-
var easeDecimal = ease || 1,
|
3706 |
-
ctx = this.chart.ctx;
|
3707 |
-
this.clear();
|
3708 |
-
this.scale.draw();
|
3709 |
-
|
3710 |
-
helpers.each(
|
3711 |
-
this.datasets,function (dataset) {
|
3712 |
-
|
3713 |
-
//Transition each point first so that the line and point drawing isn't out of sync
|
3714 |
-
helpers.each(
|
3715 |
-
dataset.points,function (point,index) {
|
3716 |
-
if (point.hasValue()) {
|
3717 |
-
point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
|
3718 |
-
}
|
3719 |
-
},this
|
3720 |
-
);
|
3721 |
-
|
3722 |
-
|
3723 |
-
|
3724 |
-
//Draw the line between all the points
|
3725 |
-
ctx.lineWidth = this.options.datasetStrokeWidth;
|
3726 |
-
ctx.strokeStyle = dataset.strokeColor;
|
3727 |
-
ctx.beginPath();
|
3728 |
-
helpers.each(
|
3729 |
-
dataset.points,function (point,index) {
|
3730 |
-
if (index === 0) {
|
3731 |
-
ctx.moveTo(point.x,point.y);
|
3732 |
-
}
|
3733 |
-
else{
|
3734 |
-
ctx.lineTo(point.x,point.y);
|
3735 |
-
}
|
3736 |
-
},this
|
3737 |
-
);
|
3738 |
-
ctx.closePath();
|
3739 |
-
ctx.stroke();
|
3740 |
-
|
3741 |
-
ctx.fillStyle = dataset.fillColor;
|
3742 |
-
ctx.fill();
|
3743 |
-
|
3744 |
-
//Now draw the points over the line
|
3745 |
-
//A little inefficient double looping, but better than the line
|
3746 |
-
//lagging behind the point positions
|
3747 |
-
helpers.each(
|
3748 |
-
dataset.points,function (point) {
|
3749 |
-
if (point.hasValue()) {
|
3750 |
-
point.draw();
|
3751 |
-
}
|
3752 |
-
}
|
3753 |
-
);
|
3754 |
-
|
3755 |
-
},this
|
3756 |
-
);
|
3757 |
-
|
3758 |
}
|
3759 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3760 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3761 |
);
|
3762 |
-
|
3763 |
-
|
3764 |
-
|
3765 |
-
|
3766 |
-
|
3767 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Chart.js v3.7.1
|
3 |
+
* https://www.chartjs.org
|
4 |
+
* (c) 2022 Chart.js Contributors
|
5 |
+
* Released under the MIT License
|
6 |
*/
|
7 |
+
(function (global, factory) {
|
8 |
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
9 |
+
typeof define === 'function' && define.amd ? define(factory) :
|
10 |
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chart = factory());
|
11 |
+
})(this, (function () { 'use strict';
|
12 |
+
|
13 |
+
function fontString(pixelSize, fontStyle, fontFamily) {
|
14 |
+
return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
|
15 |
+
}
|
16 |
+
const requestAnimFrame = (function() {
|
17 |
+
if (typeof window === 'undefined') {
|
18 |
+
return function(callback) {
|
19 |
+
return callback();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
};
|
21 |
+
}
|
22 |
+
return window.requestAnimationFrame;
|
23 |
+
}());
|
24 |
+
function throttled(fn, thisArg, updateFn) {
|
25 |
+
const updateArgs = updateFn || ((args) => Array.prototype.slice.call(args));
|
26 |
+
let ticking = false;
|
27 |
+
let args = [];
|
28 |
+
return function(...rest) {
|
29 |
+
args = updateArgs(rest);
|
30 |
+
if (!ticking) {
|
31 |
+
ticking = true;
|
32 |
+
requestAnimFrame.call(window, () => {
|
33 |
+
ticking = false;
|
34 |
+
fn.apply(thisArg, args);
|
35 |
+
});
|
36 |
+
}
|
37 |
+
};
|
38 |
+
}
|
39 |
+
function debounce(fn, delay) {
|
40 |
+
let timeout;
|
41 |
+
return function(...args) {
|
42 |
+
if (delay) {
|
43 |
+
clearTimeout(timeout);
|
44 |
+
timeout = setTimeout(fn, delay, args);
|
45 |
+
} else {
|
46 |
+
fn.apply(this, args);
|
47 |
+
}
|
48 |
+
return delay;
|
49 |
+
};
|
50 |
+
}
|
51 |
+
const _toLeftRightCenter = (align) => align === 'start' ? 'left' : align === 'end' ? 'right' : 'center';
|
52 |
+
const _alignStartEnd = (align, start, end) => align === 'start' ? start : align === 'end' ? end : (start + end) / 2;
|
53 |
+
const _textX = (align, left, right, rtl) => {
|
54 |
+
const check = rtl ? 'left' : 'right';
|
55 |
+
return align === check ? right : align === 'center' ? (left + right) / 2 : left;
|
56 |
+
};
|
57 |
+
|
58 |
+
class Animator {
|
59 |
+
constructor() {
|
60 |
+
this._request = null;
|
61 |
+
this._charts = new Map();
|
62 |
+
this._running = false;
|
63 |
+
this._lastDate = undefined;
|
64 |
+
}
|
65 |
+
_notify(chart, anims, date, type) {
|
66 |
+
const callbacks = anims.listeners[type];
|
67 |
+
const numSteps = anims.duration;
|
68 |
+
callbacks.forEach(fn => fn({
|
69 |
+
chart,
|
70 |
+
initial: anims.initial,
|
71 |
+
numSteps,
|
72 |
+
currentStep: Math.min(date - anims.start, numSteps)
|
73 |
+
}));
|
74 |
+
}
|
75 |
+
_refresh() {
|
76 |
+
if (this._request) {
|
77 |
+
return;
|
78 |
+
}
|
79 |
+
this._running = true;
|
80 |
+
this._request = requestAnimFrame.call(window, () => {
|
81 |
+
this._update();
|
82 |
+
this._request = null;
|
83 |
+
if (this._running) {
|
84 |
+
this._refresh();
|
85 |
+
}
|
86 |
+
});
|
87 |
+
}
|
88 |
+
_update(date = Date.now()) {
|
89 |
+
let remaining = 0;
|
90 |
+
this._charts.forEach((anims, chart) => {
|
91 |
+
if (!anims.running || !anims.items.length) {
|
92 |
+
return;
|
93 |
+
}
|
94 |
+
const items = anims.items;
|
95 |
+
let i = items.length - 1;
|
96 |
+
let draw = false;
|
97 |
+
let item;
|
98 |
+
for (; i >= 0; --i) {
|
99 |
+
item = items[i];
|
100 |
+
if (item._active) {
|
101 |
+
if (item._total > anims.duration) {
|
102 |
+
anims.duration = item._total;
|
103 |
+
}
|
104 |
+
item.tick(date);
|
105 |
+
draw = true;
|
106 |
+
} else {
|
107 |
+
items[i] = items[items.length - 1];
|
108 |
+
items.pop();
|
109 |
+
}
|
110 |
+
}
|
111 |
+
if (draw) {
|
112 |
+
chart.draw();
|
113 |
+
this._notify(chart, anims, date, 'progress');
|
114 |
+
}
|
115 |
+
if (!items.length) {
|
116 |
+
anims.running = false;
|
117 |
+
this._notify(chart, anims, date, 'complete');
|
118 |
+
anims.initial = false;
|
119 |
+
}
|
120 |
+
remaining += items.length;
|
121 |
+
});
|
122 |
+
this._lastDate = date;
|
123 |
+
if (remaining === 0) {
|
124 |
+
this._running = false;
|
125 |
+
}
|
126 |
+
}
|
127 |
+
_getAnims(chart) {
|
128 |
+
const charts = this._charts;
|
129 |
+
let anims = charts.get(chart);
|
130 |
+
if (!anims) {
|
131 |
+
anims = {
|
132 |
+
running: false,
|
133 |
+
initial: true,
|
134 |
+
items: [],
|
135 |
+
listeners: {
|
136 |
+
complete: [],
|
137 |
+
progress: []
|
138 |
+
}
|
139 |
+
};
|
140 |
+
charts.set(chart, anims);
|
141 |
+
}
|
142 |
+
return anims;
|
143 |
+
}
|
144 |
+
listen(chart, event, cb) {
|
145 |
+
this._getAnims(chart).listeners[event].push(cb);
|
146 |
+
}
|
147 |
+
add(chart, items) {
|
148 |
+
if (!items || !items.length) {
|
149 |
+
return;
|
150 |
+
}
|
151 |
+
this._getAnims(chart).items.push(...items);
|
152 |
+
}
|
153 |
+
has(chart) {
|
154 |
+
return this._getAnims(chart).items.length > 0;
|
155 |
+
}
|
156 |
+
start(chart) {
|
157 |
+
const anims = this._charts.get(chart);
|
158 |
+
if (!anims) {
|
159 |
+
return;
|
160 |
+
}
|
161 |
+
anims.running = true;
|
162 |
+
anims.start = Date.now();
|
163 |
+
anims.duration = anims.items.reduce((acc, cur) => Math.max(acc, cur._duration), 0);
|
164 |
+
this._refresh();
|
165 |
+
}
|
166 |
+
running(chart) {
|
167 |
+
if (!this._running) {
|
168 |
+
return false;
|
169 |
+
}
|
170 |
+
const anims = this._charts.get(chart);
|
171 |
+
if (!anims || !anims.running || !anims.items.length) {
|
172 |
+
return false;
|
173 |
+
}
|
174 |
+
return true;
|
175 |
+
}
|
176 |
+
stop(chart) {
|
177 |
+
const anims = this._charts.get(chart);
|
178 |
+
if (!anims || !anims.items.length) {
|
179 |
+
return;
|
180 |
+
}
|
181 |
+
const items = anims.items;
|
182 |
+
let i = items.length - 1;
|
183 |
+
for (; i >= 0; --i) {
|
184 |
+
items[i].cancel();
|
185 |
+
}
|
186 |
+
anims.items = [];
|
187 |
+
this._notify(chart, anims, Date.now(), 'complete');
|
188 |
+
}
|
189 |
+
remove(chart) {
|
190 |
+
return this._charts.delete(chart);
|
191 |
+
}
|
192 |
+
}
|
193 |
+
var animator = new Animator();
|
194 |
+
|
195 |
+
/*!
|
196 |
+
* @kurkle/color v0.1.9
|
197 |
+
* https://github.com/kurkle/color#readme
|
198 |
+
* (c) 2020 Jukka Kurkela
|
199 |
+
* Released under the MIT License
|
200 |
+
*/
|
201 |
+
const map$1 = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15};
|
202 |
+
const hex = '0123456789ABCDEF';
|
203 |
+
const h1 = (b) => hex[b & 0xF];
|
204 |
+
const h2 = (b) => hex[(b & 0xF0) >> 4] + hex[b & 0xF];
|
205 |
+
const eq = (b) => (((b & 0xF0) >> 4) === (b & 0xF));
|
206 |
+
function isShort(v) {
|
207 |
+
return eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);
|
208 |
+
}
|
209 |
+
function hexParse(str) {
|
210 |
+
var len = str.length;
|
211 |
+
var ret;
|
212 |
+
if (str[0] === '#') {
|
213 |
+
if (len === 4 || len === 5) {
|
214 |
+
ret = {
|
215 |
+
r: 255 & map$1[str[1]] * 17,
|
216 |
+
g: 255 & map$1[str[2]] * 17,
|
217 |
+
b: 255 & map$1[str[3]] * 17,
|
218 |
+
a: len === 5 ? map$1[str[4]] * 17 : 255
|
219 |
+
};
|
220 |
+
} else if (len === 7 || len === 9) {
|
221 |
+
ret = {
|
222 |
+
r: map$1[str[1]] << 4 | map$1[str[2]],
|
223 |
+
g: map$1[str[3]] << 4 | map$1[str[4]],
|
224 |
+
b: map$1[str[5]] << 4 | map$1[str[6]],
|
225 |
+
a: len === 9 ? (map$1[str[7]] << 4 | map$1[str[8]]) : 255
|
226 |
+
};
|
227 |
}
|
228 |
+
}
|
229 |
+
return ret;
|
230 |
+
}
|
231 |
+
function hexString(v) {
|
232 |
+
var f = isShort(v) ? h1 : h2;
|
233 |
+
return v
|
234 |
+
? '#' + f(v.r) + f(v.g) + f(v.b) + (v.a < 255 ? f(v.a) : '')
|
235 |
+
: v;
|
236 |
+
}
|
237 |
+
function round(v) {
|
238 |
+
return v + 0.5 | 0;
|
239 |
+
}
|
240 |
+
const lim = (v, l, h) => Math.max(Math.min(v, h), l);
|
241 |
+
function p2b(v) {
|
242 |
+
return lim(round(v * 2.55), 0, 255);
|
243 |
+
}
|
244 |
+
function n2b(v) {
|
245 |
+
return lim(round(v * 255), 0, 255);
|
246 |
+
}
|
247 |
+
function b2n(v) {
|
248 |
+
return lim(round(v / 2.55) / 100, 0, 1);
|
249 |
+
}
|
250 |
+
function n2p(v) {
|
251 |
+
return lim(round(v * 100), 0, 100);
|
252 |
+
}
|
253 |
+
const RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;
|
254 |
+
function rgbParse(str) {
|
255 |
+
const m = RGB_RE.exec(str);
|
256 |
+
let a = 255;
|
257 |
+
let r, g, b;
|
258 |
+
if (!m) {
|
259 |
+
return;
|
260 |
+
}
|
261 |
+
if (m[7] !== r) {
|
262 |
+
const v = +m[7];
|
263 |
+
a = 255 & (m[8] ? p2b(v) : v * 255);
|
264 |
+
}
|
265 |
+
r = +m[1];
|
266 |
+
g = +m[3];
|
267 |
+
b = +m[5];
|
268 |
+
r = 255 & (m[2] ? p2b(r) : r);
|
269 |
+
g = 255 & (m[4] ? p2b(g) : g);
|
270 |
+
b = 255 & (m[6] ? p2b(b) : b);
|
271 |
+
return {
|
272 |
+
r: r,
|
273 |
+
g: g,
|
274 |
+
b: b,
|
275 |
+
a: a
|
276 |
};
|
277 |
+
}
|
278 |
+
function rgbString(v) {
|
279 |
+
return v && (
|
280 |
+
v.a < 255
|
281 |
+
? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})`
|
282 |
+
: `rgb(${v.r}, ${v.g}, ${v.b})`
|
283 |
+
);
|
284 |
+
}
|
285 |
+
const HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
|
286 |
+
function hsl2rgbn(h, s, l) {
|
287 |
+
const a = s * Math.min(l, 1 - l);
|
288 |
+
const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
289 |
+
return [f(0), f(8), f(4)];
|
290 |
+
}
|
291 |
+
function hsv2rgbn(h, s, v) {
|
292 |
+
const f = (n, k = (n + h / 60) % 6) => v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
|
293 |
+
return [f(5), f(3), f(1)];
|
294 |
+
}
|
295 |
+
function hwb2rgbn(h, w, b) {
|
296 |
+
const rgb = hsl2rgbn(h, 1, 0.5);
|
297 |
+
let i;
|
298 |
+
if (w + b > 1) {
|
299 |
+
i = 1 / (w + b);
|
300 |
+
w *= i;
|
301 |
+
b *= i;
|
302 |
+
}
|
303 |
+
for (i = 0; i < 3; i++) {
|
304 |
+
rgb[i] *= 1 - w - b;
|
305 |
+
rgb[i] += w;
|
306 |
+
}
|
307 |
+
return rgb;
|
308 |
+
}
|
309 |
+
function rgb2hsl(v) {
|
310 |
+
const range = 255;
|
311 |
+
const r = v.r / range;
|
312 |
+
const g = v.g / range;
|
313 |
+
const b = v.b / range;
|
314 |
+
const max = Math.max(r, g, b);
|
315 |
+
const min = Math.min(r, g, b);
|
316 |
+
const l = (max + min) / 2;
|
317 |
+
let h, s, d;
|
318 |
+
if (max !== min) {
|
319 |
+
d = max - min;
|
320 |
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
321 |
+
h = max === r
|
322 |
+
? ((g - b) / d) + (g < b ? 6 : 0)
|
323 |
+
: max === g
|
324 |
+
? (b - r) / d + 2
|
325 |
+
: (r - g) / d + 4;
|
326 |
+
h = h * 60 + 0.5;
|
327 |
+
}
|
328 |
+
return [h | 0, s || 0, l];
|
329 |
+
}
|
330 |
+
function calln(f, a, b, c) {
|
331 |
+
return (
|
332 |
+
Array.isArray(a)
|
333 |
+
? f(a[0], a[1], a[2])
|
334 |
+
: f(a, b, c)
|
335 |
+
).map(n2b);
|
336 |
+
}
|
337 |
+
function hsl2rgb(h, s, l) {
|
338 |
+
return calln(hsl2rgbn, h, s, l);
|
339 |
+
}
|
340 |
+
function hwb2rgb(h, w, b) {
|
341 |
+
return calln(hwb2rgbn, h, w, b);
|
342 |
+
}
|
343 |
+
function hsv2rgb(h, s, v) {
|
344 |
+
return calln(hsv2rgbn, h, s, v);
|
345 |
+
}
|
346 |
+
function hue(h) {
|
347 |
+
return (h % 360 + 360) % 360;
|
348 |
+
}
|
349 |
+
function hueParse(str) {
|
350 |
+
const m = HUE_RE.exec(str);
|
351 |
+
let a = 255;
|
352 |
+
let v;
|
353 |
+
if (!m) {
|
354 |
+
return;
|
355 |
+
}
|
356 |
+
if (m[5] !== v) {
|
357 |
+
a = m[6] ? p2b(+m[5]) : n2b(+m[5]);
|
358 |
+
}
|
359 |
+
const h = hue(+m[2]);
|
360 |
+
const p1 = +m[3] / 100;
|
361 |
+
const p2 = +m[4] / 100;
|
362 |
+
if (m[1] === 'hwb') {
|
363 |
+
v = hwb2rgb(h, p1, p2);
|
364 |
+
} else if (m[1] === 'hsv') {
|
365 |
+
v = hsv2rgb(h, p1, p2);
|
366 |
+
} else {
|
367 |
+
v = hsl2rgb(h, p1, p2);
|
368 |
+
}
|
369 |
+
return {
|
370 |
+
r: v[0],
|
371 |
+
g: v[1],
|
372 |
+
b: v[2],
|
373 |
+
a: a
|
374 |
+
};
|
375 |
+
}
|
376 |
+
function rotate(v, deg) {
|
377 |
+
var h = rgb2hsl(v);
|
378 |
+
h[0] = hue(h[0] + deg);
|
379 |
+
h = hsl2rgb(h);
|
380 |
+
v.r = h[0];
|
381 |
+
v.g = h[1];
|
382 |
+
v.b = h[2];
|
383 |
+
}
|
384 |
+
function hslString(v) {
|
385 |
+
if (!v) {
|
386 |
+
return;
|
387 |
+
}
|
388 |
+
const a = rgb2hsl(v);
|
389 |
+
const h = a[0];
|
390 |
+
const s = n2p(a[1]);
|
391 |
+
const l = n2p(a[2]);
|
392 |
+
return v.a < 255
|
393 |
+
? `hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})`
|
394 |
+
: `hsl(${h}, ${s}%, ${l}%)`;
|
395 |
+
}
|
396 |
+
const map$1$1 = {
|
397 |
+
x: 'dark',
|
398 |
+
Z: 'light',
|
399 |
+
Y: 're',
|
400 |
+
X: 'blu',
|
401 |
+
W: 'gr',
|
402 |
+
V: 'medium',
|
403 |
+
U: 'slate',
|
404 |
+
A: 'ee',
|
405 |
+
T: 'ol',
|
406 |
+
S: 'or',
|
407 |
+
B: 'ra',
|
408 |
+
C: 'lateg',
|
409 |
+
D: 'ights',
|
410 |
+
R: 'in',
|
411 |
+
Q: 'turquois',
|
412 |
+
E: 'hi',
|
413 |
+
P: 'ro',
|
414 |
+
O: 'al',
|
415 |
+
N: 'le',
|
416 |
+
M: 'de',
|
417 |
+
L: 'yello',
|
418 |
+
F: 'en',
|
419 |
+
K: 'ch',
|
420 |
+
G: 'arks',
|
421 |
+
H: 'ea',
|
422 |
+
I: 'ightg',
|
423 |
+
J: 'wh'
|
424 |
+
};
|
425 |
+
const names = {
|
426 |
+
OiceXe: 'f0f8ff',
|
427 |
+
antiquewEte: 'faebd7',
|
428 |
+
aqua: 'ffff',
|
429 |
+
aquamarRe: '7fffd4',
|
430 |
+
azuY: 'f0ffff',
|
431 |
+
beige: 'f5f5dc',
|
432 |
+
bisque: 'ffe4c4',
|
433 |
+
black: '0',
|
434 |
+
blanKedOmond: 'ffebcd',
|
435 |
+
Xe: 'ff',
|
436 |
+
XeviTet: '8a2be2',
|
437 |
+
bPwn: 'a52a2a',
|
438 |
+
burlywood: 'deb887',
|
439 |
+
caMtXe: '5f9ea0',
|
440 |
+
KartYuse: '7fff00',
|
441 |
+
KocTate: 'd2691e',
|
442 |
+
cSO: 'ff7f50',
|
443 |
+
cSnflowerXe: '6495ed',
|
444 |
+
cSnsilk: 'fff8dc',
|
445 |
+
crimson: 'dc143c',
|
446 |
+
cyan: 'ffff',
|
447 |
+
xXe: '8b',
|
448 |
+
xcyan: '8b8b',
|
449 |
+
xgTMnPd: 'b8860b',
|
450 |
+
xWay: 'a9a9a9',
|
451 |
+
xgYF: '6400',
|
452 |
+
xgYy: 'a9a9a9',
|
453 |
+
xkhaki: 'bdb76b',
|
454 |
+
xmagFta: '8b008b',
|
455 |
+
xTivegYF: '556b2f',
|
456 |
+
xSange: 'ff8c00',
|
457 |
+
xScEd: '9932cc',
|
458 |
+
xYd: '8b0000',
|
459 |
+
xsOmon: 'e9967a',
|
460 |
+
xsHgYF: '8fbc8f',
|
461 |
+
xUXe: '483d8b',
|
462 |
+
xUWay: '2f4f4f',
|
463 |
+
xUgYy: '2f4f4f',
|
464 |
+
xQe: 'ced1',
|
465 |
+
xviTet: '9400d3',
|
466 |
+
dAppRk: 'ff1493',
|
467 |
+
dApskyXe: 'bfff',
|
468 |
+
dimWay: '696969',
|
469 |
+
dimgYy: '696969',
|
470 |
+
dodgerXe: '1e90ff',
|
471 |
+
fiYbrick: 'b22222',
|
472 |
+
flSOwEte: 'fffaf0',
|
473 |
+
foYstWAn: '228b22',
|
474 |
+
fuKsia: 'ff00ff',
|
475 |
+
gaRsbSo: 'dcdcdc',
|
476 |
+
ghostwEte: 'f8f8ff',
|
477 |
+
gTd: 'ffd700',
|
478 |
+
gTMnPd: 'daa520',
|
479 |
+
Way: '808080',
|
480 |
+
gYF: '8000',
|
481 |
+
gYFLw: 'adff2f',
|
482 |
+
gYy: '808080',
|
483 |
+
honeyMw: 'f0fff0',
|
484 |
+
hotpRk: 'ff69b4',
|
485 |
+
RdianYd: 'cd5c5c',
|
486 |
+
Rdigo: '4b0082',
|
487 |
+
ivSy: 'fffff0',
|
488 |
+
khaki: 'f0e68c',
|
489 |
+
lavFMr: 'e6e6fa',
|
490 |
+
lavFMrXsh: 'fff0f5',
|
491 |
+
lawngYF: '7cfc00',
|
492 |
+
NmoncEffon: 'fffacd',
|
493 |
+
ZXe: 'add8e6',
|
494 |
+
ZcSO: 'f08080',
|
495 |
+
Zcyan: 'e0ffff',
|
496 |
+
ZgTMnPdLw: 'fafad2',
|
497 |
+
ZWay: 'd3d3d3',
|
498 |
+
ZgYF: '90ee90',
|
499 |
+
ZgYy: 'd3d3d3',
|
500 |
+
ZpRk: 'ffb6c1',
|
501 |
+
ZsOmon: 'ffa07a',
|
502 |
+
ZsHgYF: '20b2aa',
|
503 |
+
ZskyXe: '87cefa',
|
504 |
+
ZUWay: '778899',
|
505 |
+
ZUgYy: '778899',
|
506 |
+
ZstAlXe: 'b0c4de',
|
507 |
+
ZLw: 'ffffe0',
|
508 |
+
lime: 'ff00',
|
509 |
+
limegYF: '32cd32',
|
510 |
+
lRF: 'faf0e6',
|
511 |
+
magFta: 'ff00ff',
|
512 |
+
maPon: '800000',
|
513 |
+
VaquamarRe: '66cdaa',
|
514 |
+
VXe: 'cd',
|
515 |
+
VScEd: 'ba55d3',
|
516 |
+
VpurpN: '9370db',
|
517 |
+
VsHgYF: '3cb371',
|
518 |
+
VUXe: '7b68ee',
|
519 |
+
VsprRggYF: 'fa9a',
|
520 |
+
VQe: '48d1cc',
|
521 |
+
VviTetYd: 'c71585',
|
522 |
+
midnightXe: '191970',
|
523 |
+
mRtcYam: 'f5fffa',
|
524 |
+
mistyPse: 'ffe4e1',
|
525 |
+
moccasR: 'ffe4b5',
|
526 |
+
navajowEte: 'ffdead',
|
527 |
+
navy: '80',
|
528 |
+
Tdlace: 'fdf5e6',
|
529 |
+
Tive: '808000',
|
530 |
+
TivedBb: '6b8e23',
|
531 |
+
Sange: 'ffa500',
|
532 |
+
SangeYd: 'ff4500',
|
533 |
+
ScEd: 'da70d6',
|
534 |
+
pOegTMnPd: 'eee8aa',
|
535 |
+
pOegYF: '98fb98',
|
536 |
+
pOeQe: 'afeeee',
|
537 |
+
pOeviTetYd: 'db7093',
|
538 |
+
papayawEp: 'ffefd5',
|
539 |
+
pHKpuff: 'ffdab9',
|
540 |
+
peru: 'cd853f',
|
541 |
+
pRk: 'ffc0cb',
|
542 |
+
plum: 'dda0dd',
|
543 |
+
powMrXe: 'b0e0e6',
|
544 |
+
purpN: '800080',
|
545 |
+
YbeccapurpN: '663399',
|
546 |
+
Yd: 'ff0000',
|
547 |
+
Psybrown: 'bc8f8f',
|
548 |
+
PyOXe: '4169e1',
|
549 |
+
saddNbPwn: '8b4513',
|
550 |
+
sOmon: 'fa8072',
|
551 |
+
sandybPwn: 'f4a460',
|
552 |
+
sHgYF: '2e8b57',
|
553 |
+
sHshell: 'fff5ee',
|
554 |
+
siFna: 'a0522d',
|
555 |
+
silver: 'c0c0c0',
|
556 |
+
skyXe: '87ceeb',
|
557 |
+
UXe: '6a5acd',
|
558 |
+
UWay: '708090',
|
559 |
+
UgYy: '708090',
|
560 |
+
snow: 'fffafa',
|
561 |
+
sprRggYF: 'ff7f',
|
562 |
+
stAlXe: '4682b4',
|
563 |
+
tan: 'd2b48c',
|
564 |
+
teO: '8080',
|
565 |
+
tEstN: 'd8bfd8',
|
566 |
+
tomato: 'ff6347',
|
567 |
+
Qe: '40e0d0',
|
568 |
+
viTet: 'ee82ee',
|
569 |
+
JHt: 'f5deb3',
|
570 |
+
wEte: 'ffffff',
|
571 |
+
wEtesmoke: 'f5f5f5',
|
572 |
+
Lw: 'ffff00',
|
573 |
+
LwgYF: '9acd32'
|
574 |
+
};
|
575 |
+
function unpack() {
|
576 |
+
const unpacked = {};
|
577 |
+
const keys = Object.keys(names);
|
578 |
+
const tkeys = Object.keys(map$1$1);
|
579 |
+
let i, j, k, ok, nk;
|
580 |
+
for (i = 0; i < keys.length; i++) {
|
581 |
+
ok = nk = keys[i];
|
582 |
+
for (j = 0; j < tkeys.length; j++) {
|
583 |
+
k = tkeys[j];
|
584 |
+
nk = nk.replace(k, map$1$1[k]);
|
585 |
}
|
586 |
+
k = parseInt(names[ok], 16);
|
587 |
+
unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF];
|
588 |
+
}
|
589 |
+
return unpacked;
|
590 |
+
}
|
591 |
+
let names$1;
|
592 |
+
function nameParse(str) {
|
593 |
+
if (!names$1) {
|
594 |
+
names$1 = unpack();
|
595 |
+
names$1.transparent = [0, 0, 0, 0];
|
596 |
+
}
|
597 |
+
const a = names$1[str.toLowerCase()];
|
598 |
+
return a && {
|
599 |
+
r: a[0],
|
600 |
+
g: a[1],
|
601 |
+
b: a[2],
|
602 |
+
a: a.length === 4 ? a[3] : 255
|
603 |
+
};
|
604 |
+
}
|
605 |
+
function modHSL(v, i, ratio) {
|
606 |
+
if (v) {
|
607 |
+
let tmp = rgb2hsl(v);
|
608 |
+
tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1));
|
609 |
+
tmp = hsl2rgb(tmp);
|
610 |
+
v.r = tmp[0];
|
611 |
+
v.g = tmp[1];
|
612 |
+
v.b = tmp[2];
|
613 |
+
}
|
614 |
+
}
|
615 |
+
function clone$1(v, proto) {
|
616 |
+
return v ? Object.assign(proto || {}, v) : v;
|
617 |
+
}
|
618 |
+
function fromObject(input) {
|
619 |
+
var v = {r: 0, g: 0, b: 0, a: 255};
|
620 |
+
if (Array.isArray(input)) {
|
621 |
+
if (input.length >= 3) {
|
622 |
+
v = {r: input[0], g: input[1], b: input[2], a: 255};
|
623 |
+
if (input.length > 3) {
|
624 |
+
v.a = n2b(input[3]);
|
625 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
626 |
}
|
627 |
+
} else {
|
628 |
+
v = clone$1(input, {r: 0, g: 0, b: 0, a: 1});
|
629 |
+
v.a = n2b(v.a);
|
630 |
+
}
|
631 |
+
return v;
|
632 |
+
}
|
633 |
+
function functionParse(str) {
|
634 |
+
if (str.charAt(0) === 'r') {
|
635 |
+
return rgbParse(str);
|
636 |
+
}
|
637 |
+
return hueParse(str);
|
638 |
+
}
|
639 |
+
class Color {
|
640 |
+
constructor(input) {
|
641 |
+
if (input instanceof Color) {
|
642 |
+
return input;
|
643 |
}
|
644 |
+
const type = typeof input;
|
645 |
+
let v;
|
646 |
+
if (type === 'object') {
|
647 |
+
v = fromObject(input);
|
648 |
+
} else if (type === 'string') {
|
649 |
+
v = hexParse(input) || nameParse(input) || functionParse(input);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
650 |
}
|
651 |
+
this._rgb = v;
|
652 |
+
this._valid = !!v;
|
653 |
+
}
|
654 |
+
get valid() {
|
655 |
+
return this._valid;
|
656 |
+
}
|
657 |
+
get rgb() {
|
658 |
+
var v = clone$1(this._rgb);
|
659 |
+
if (v) {
|
660 |
+
v.a = b2n(v.a);
|
661 |
}
|
662 |
+
return v;
|
663 |
+
}
|
664 |
+
set rgb(obj) {
|
665 |
+
this._rgb = fromObject(obj);
|
666 |
+
}
|
667 |
+
rgbString() {
|
668 |
+
return this._valid ? rgbString(this._rgb) : this._rgb;
|
669 |
+
}
|
670 |
+
hexString() {
|
671 |
+
return this._valid ? hexString(this._rgb) : this._rgb;
|
672 |
+
}
|
673 |
+
hslString() {
|
674 |
+
return this._valid ? hslString(this._rgb) : this._rgb;
|
675 |
+
}
|
676 |
+
mix(color, weight) {
|
677 |
+
const me = this;
|
678 |
+
if (color) {
|
679 |
+
const c1 = me.rgb;
|
680 |
+
const c2 = color.rgb;
|
681 |
+
let w2;
|
682 |
+
const p = weight === w2 ? 0.5 : weight;
|
683 |
+
const w = 2 * p - 1;
|
684 |
+
const a = c1.a - c2.a;
|
685 |
+
const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
|
686 |
+
w2 = 1 - w1;
|
687 |
+
c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5;
|
688 |
+
c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5;
|
689 |
+
c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5;
|
690 |
+
c1.a = p * c1.a + (1 - p) * c2.a;
|
691 |
+
me.rgb = c1;
|
692 |
}
|
693 |
+
return me;
|
694 |
+
}
|
695 |
+
clone() {
|
696 |
+
return new Color(this.rgb);
|
697 |
+
}
|
698 |
+
alpha(a) {
|
699 |
+
this._rgb.a = n2b(a);
|
700 |
+
return this;
|
701 |
+
}
|
702 |
+
clearer(ratio) {
|
703 |
+
const rgb = this._rgb;
|
704 |
+
rgb.a *= 1 - ratio;
|
705 |
+
return this;
|
706 |
+
}
|
707 |
+
greyscale() {
|
708 |
+
const rgb = this._rgb;
|
709 |
+
const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11);
|
710 |
+
rgb.r = rgb.g = rgb.b = val;
|
711 |
+
return this;
|
712 |
+
}
|
713 |
+
opaquer(ratio) {
|
714 |
+
const rgb = this._rgb;
|
715 |
+
rgb.a *= 1 + ratio;
|
716 |
+
return this;
|
717 |
+
}
|
718 |
+
negate() {
|
719 |
+
const v = this._rgb;
|
720 |
+
v.r = 255 - v.r;
|
721 |
+
v.g = 255 - v.g;
|
722 |
+
v.b = 255 - v.b;
|
723 |
+
return this;
|
724 |
+
}
|
725 |
+
lighten(ratio) {
|
726 |
+
modHSL(this._rgb, 2, ratio);
|
727 |
+
return this;
|
728 |
+
}
|
729 |
+
darken(ratio) {
|
730 |
+
modHSL(this._rgb, 2, -ratio);
|
731 |
+
return this;
|
732 |
+
}
|
733 |
+
saturate(ratio) {
|
734 |
+
modHSL(this._rgb, 1, ratio);
|
735 |
+
return this;
|
736 |
+
}
|
737 |
+
desaturate(ratio) {
|
738 |
+
modHSL(this._rgb, 1, -ratio);
|
739 |
+
return this;
|
740 |
+
}
|
741 |
+
rotate(deg) {
|
742 |
+
rotate(this._rgb, deg);
|
743 |
+
return this;
|
744 |
+
}
|
745 |
+
}
|
746 |
+
function index_esm(input) {
|
747 |
+
return new Color(input);
|
748 |
+
}
|
749 |
+
|
750 |
+
const isPatternOrGradient = (value) => value instanceof CanvasGradient || value instanceof CanvasPattern;
|
751 |
+
function color(value) {
|
752 |
+
return isPatternOrGradient(value) ? value : index_esm(value);
|
753 |
+
}
|
754 |
+
function getHoverColor(value) {
|
755 |
+
return isPatternOrGradient(value)
|
756 |
+
? value
|
757 |
+
: index_esm(value).saturate(0.5).darken(0.1).hexString();
|
758 |
+
}
|
759 |
+
|
760 |
+
function noop() {}
|
761 |
+
const uid = (function() {
|
762 |
+
let id = 0;
|
763 |
+
return function() {
|
764 |
+
return id++;
|
765 |
+
};
|
766 |
+
}());
|
767 |
+
function isNullOrUndef(value) {
|
768 |
+
return value === null || typeof value === 'undefined';
|
769 |
+
}
|
770 |
+
function isArray(value) {
|
771 |
+
if (Array.isArray && Array.isArray(value)) {
|
772 |
+
return true;
|
773 |
+
}
|
774 |
+
const type = Object.prototype.toString.call(value);
|
775 |
+
if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') {
|
776 |
+
return true;
|
777 |
+
}
|
778 |
+
return false;
|
779 |
+
}
|
780 |
+
function isObject(value) {
|
781 |
+
return value !== null && Object.prototype.toString.call(value) === '[object Object]';
|
782 |
+
}
|
783 |
+
const isNumberFinite = (value) => (typeof value === 'number' || value instanceof Number) && isFinite(+value);
|
784 |
+
function finiteOrDefault(value, defaultValue) {
|
785 |
+
return isNumberFinite(value) ? value : defaultValue;
|
786 |
+
}
|
787 |
+
function valueOrDefault(value, defaultValue) {
|
788 |
+
return typeof value === 'undefined' ? defaultValue : value;
|
789 |
+
}
|
790 |
+
const toPercentage = (value, dimension) =>
|
791 |
+
typeof value === 'string' && value.endsWith('%') ?
|
792 |
+
parseFloat(value) / 100
|
793 |
+
: value / dimension;
|
794 |
+
const toDimension = (value, dimension) =>
|
795 |
+
typeof value === 'string' && value.endsWith('%') ?
|
796 |
+
parseFloat(value) / 100 * dimension
|
797 |
+
: +value;
|
798 |
+
function callback(fn, args, thisArg) {
|
799 |
+
if (fn && typeof fn.call === 'function') {
|
800 |
+
return fn.apply(thisArg, args);
|
801 |
+
}
|
802 |
+
}
|
803 |
+
function each(loopable, fn, thisArg, reverse) {
|
804 |
+
let i, len, keys;
|
805 |
+
if (isArray(loopable)) {
|
806 |
+
len = loopable.length;
|
807 |
+
if (reverse) {
|
808 |
+
for (i = len - 1; i >= 0; i--) {
|
809 |
+
fn.call(thisArg, loopable[i], i);
|
810 |
+
}
|
811 |
+
} else {
|
812 |
+
for (i = 0; i < len; i++) {
|
813 |
+
fn.call(thisArg, loopable[i], i);
|
814 |
+
}
|
815 |
+
}
|
816 |
+
} else if (isObject(loopable)) {
|
817 |
+
keys = Object.keys(loopable);
|
818 |
+
len = keys.length;
|
819 |
+
for (i = 0; i < len; i++) {
|
820 |
+
fn.call(thisArg, loopable[keys[i]], keys[i]);
|
821 |
+
}
|
822 |
+
}
|
823 |
+
}
|
824 |
+
function _elementsEqual(a0, a1) {
|
825 |
+
let i, ilen, v0, v1;
|
826 |
+
if (!a0 || !a1 || a0.length !== a1.length) {
|
827 |
+
return false;
|
828 |
+
}
|
829 |
+
for (i = 0, ilen = a0.length; i < ilen; ++i) {
|
830 |
+
v0 = a0[i];
|
831 |
+
v1 = a1[i];
|
832 |
+
if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) {
|
833 |
+
return false;
|
834 |
+
}
|
835 |
+
}
|
836 |
+
return true;
|
837 |
+
}
|
838 |
+
function clone(source) {
|
839 |
+
if (isArray(source)) {
|
840 |
+
return source.map(clone);
|
841 |
+
}
|
842 |
+
if (isObject(source)) {
|
843 |
+
const target = Object.create(null);
|
844 |
+
const keys = Object.keys(source);
|
845 |
+
const klen = keys.length;
|
846 |
+
let k = 0;
|
847 |
+
for (; k < klen; ++k) {
|
848 |
+
target[keys[k]] = clone(source[keys[k]]);
|
849 |
+
}
|
850 |
+
return target;
|
851 |
+
}
|
852 |
+
return source;
|
853 |
+
}
|
854 |
+
function isValidKey(key) {
|
855 |
+
return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1;
|
856 |
+
}
|
857 |
+
function _merger(key, target, source, options) {
|
858 |
+
if (!isValidKey(key)) {
|
859 |
+
return;
|
860 |
+
}
|
861 |
+
const tval = target[key];
|
862 |
+
const sval = source[key];
|
863 |
+
if (isObject(tval) && isObject(sval)) {
|
864 |
+
merge(tval, sval, options);
|
865 |
+
} else {
|
866 |
+
target[key] = clone(sval);
|
867 |
+
}
|
868 |
+
}
|
869 |
+
function merge(target, source, options) {
|
870 |
+
const sources = isArray(source) ? source : [source];
|
871 |
+
const ilen = sources.length;
|
872 |
+
if (!isObject(target)) {
|
873 |
+
return target;
|
874 |
+
}
|
875 |
+
options = options || {};
|
876 |
+
const merger = options.merger || _merger;
|
877 |
+
for (let i = 0; i < ilen; ++i) {
|
878 |
+
source = sources[i];
|
879 |
+
if (!isObject(source)) {
|
880 |
+
continue;
|
881 |
+
}
|
882 |
+
const keys = Object.keys(source);
|
883 |
+
for (let k = 0, klen = keys.length; k < klen; ++k) {
|
884 |
+
merger(keys[k], target, source, options);
|
885 |
+
}
|
886 |
+
}
|
887 |
+
return target;
|
888 |
+
}
|
889 |
+
function mergeIf(target, source) {
|
890 |
+
return merge(target, source, {merger: _mergerIf});
|
891 |
+
}
|
892 |
+
function _mergerIf(key, target, source) {
|
893 |
+
if (!isValidKey(key)) {
|
894 |
+
return;
|
895 |
+
}
|
896 |
+
const tval = target[key];
|
897 |
+
const sval = source[key];
|
898 |
+
if (isObject(tval) && isObject(sval)) {
|
899 |
+
mergeIf(tval, sval);
|
900 |
+
} else if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
901 |
+
target[key] = clone(sval);
|
902 |
+
}
|
903 |
+
}
|
904 |
+
function _deprecated(scope, value, previous, current) {
|
905 |
+
if (value !== undefined) {
|
906 |
+
console.warn(scope + ': "' + previous +
|
907 |
+
'" is deprecated. Please use "' + current + '" instead');
|
908 |
+
}
|
909 |
+
}
|
910 |
+
const emptyString = '';
|
911 |
+
const dot = '.';
|
912 |
+
function indexOfDotOrLength(key, start) {
|
913 |
+
const idx = key.indexOf(dot, start);
|
914 |
+
return idx === -1 ? key.length : idx;
|
915 |
+
}
|
916 |
+
function resolveObjectKey(obj, key) {
|
917 |
+
if (key === emptyString) {
|
918 |
+
return obj;
|
919 |
+
}
|
920 |
+
let pos = 0;
|
921 |
+
let idx = indexOfDotOrLength(key, pos);
|
922 |
+
while (obj && idx > pos) {
|
923 |
+
obj = obj[key.substr(pos, idx - pos)];
|
924 |
+
pos = idx + 1;
|
925 |
+
idx = indexOfDotOrLength(key, pos);
|
926 |
+
}
|
927 |
+
return obj;
|
928 |
+
}
|
929 |
+
function _capitalize(str) {
|
930 |
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
931 |
+
}
|
932 |
+
const defined = (value) => typeof value !== 'undefined';
|
933 |
+
const isFunction = (value) => typeof value === 'function';
|
934 |
+
const setsEqual = (a, b) => {
|
935 |
+
if (a.size !== b.size) {
|
936 |
+
return false;
|
937 |
+
}
|
938 |
+
for (const item of a) {
|
939 |
+
if (!b.has(item)) {
|
940 |
+
return false;
|
941 |
+
}
|
942 |
+
}
|
943 |
+
return true;
|
944 |
+
};
|
945 |
+
function _isClickEvent(e) {
|
946 |
+
return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu';
|
947 |
+
}
|
948 |
+
|
949 |
+
const overrides = Object.create(null);
|
950 |
+
const descriptors = Object.create(null);
|
951 |
+
function getScope$1(node, key) {
|
952 |
+
if (!key) {
|
953 |
+
return node;
|
954 |
+
}
|
955 |
+
const keys = key.split('.');
|
956 |
+
for (let i = 0, n = keys.length; i < n; ++i) {
|
957 |
+
const k = keys[i];
|
958 |
+
node = node[k] || (node[k] = Object.create(null));
|
959 |
+
}
|
960 |
+
return node;
|
961 |
+
}
|
962 |
+
function set(root, scope, values) {
|
963 |
+
if (typeof scope === 'string') {
|
964 |
+
return merge(getScope$1(root, scope), values);
|
965 |
+
}
|
966 |
+
return merge(getScope$1(root, ''), scope);
|
967 |
+
}
|
968 |
+
class Defaults {
|
969 |
+
constructor(_descriptors) {
|
970 |
+
this.animation = undefined;
|
971 |
+
this.backgroundColor = 'rgba(0,0,0,0.1)';
|
972 |
+
this.borderColor = 'rgba(0,0,0,0.1)';
|
973 |
+
this.color = '#666';
|
974 |
+
this.datasets = {};
|
975 |
+
this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio();
|
976 |
+
this.elements = {};
|
977 |
+
this.events = [
|
978 |
+
'mousemove',
|
979 |
+
'mouseout',
|
980 |
+
'click',
|
981 |
+
'touchstart',
|
982 |
+
'touchmove'
|
983 |
+
];
|
984 |
+
this.font = {
|
985 |
+
family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
|
986 |
+
size: 12,
|
987 |
+
style: 'normal',
|
988 |
+
lineHeight: 1.2,
|
989 |
+
weight: null
|
990 |
+
};
|
991 |
+
this.hover = {};
|
992 |
+
this.hoverBackgroundColor = (ctx, options) => getHoverColor(options.backgroundColor);
|
993 |
+
this.hoverBorderColor = (ctx, options) => getHoverColor(options.borderColor);
|
994 |
+
this.hoverColor = (ctx, options) => getHoverColor(options.color);
|
995 |
+
this.indexAxis = 'x';
|
996 |
+
this.interaction = {
|
997 |
+
mode: 'nearest',
|
998 |
+
intersect: true
|
999 |
+
};
|
1000 |
+
this.maintainAspectRatio = true;
|
1001 |
+
this.onHover = null;
|
1002 |
+
this.onClick = null;
|
1003 |
+
this.parsing = true;
|
1004 |
+
this.plugins = {};
|
1005 |
+
this.responsive = true;
|
1006 |
+
this.scale = undefined;
|
1007 |
+
this.scales = {};
|
1008 |
+
this.showLine = true;
|
1009 |
+
this.drawActiveElementsOnTop = true;
|
1010 |
+
this.describe(_descriptors);
|
1011 |
+
}
|
1012 |
+
set(scope, values) {
|
1013 |
+
return set(this, scope, values);
|
1014 |
+
}
|
1015 |
+
get(scope) {
|
1016 |
+
return getScope$1(this, scope);
|
1017 |
+
}
|
1018 |
+
describe(scope, values) {
|
1019 |
+
return set(descriptors, scope, values);
|
1020 |
+
}
|
1021 |
+
override(scope, values) {
|
1022 |
+
return set(overrides, scope, values);
|
1023 |
+
}
|
1024 |
+
route(scope, name, targetScope, targetName) {
|
1025 |
+
const scopeObject = getScope$1(this, scope);
|
1026 |
+
const targetScopeObject = getScope$1(this, targetScope);
|
1027 |
+
const privateName = '_' + name;
|
1028 |
+
Object.defineProperties(scopeObject, {
|
1029 |
+
[privateName]: {
|
1030 |
+
value: scopeObject[name],
|
1031 |
+
writable: true
|
1032 |
+
},
|
1033 |
+
[name]: {
|
1034 |
+
enumerable: true,
|
1035 |
+
get() {
|
1036 |
+
const local = this[privateName];
|
1037 |
+
const target = targetScopeObject[targetName];
|
1038 |
+
if (isObject(local)) {
|
1039 |
+
return Object.assign({}, target, local);
|
1040 |
+
}
|
1041 |
+
return valueOrDefault(local, target);
|
1042 |
+
},
|
1043 |
+
set(value) {
|
1044 |
+
this[privateName] = value;
|
1045 |
}
|
1046 |
+
}
|
1047 |
+
});
|
1048 |
+
}
|
1049 |
+
}
|
1050 |
+
var defaults = new Defaults({
|
1051 |
+
_scriptable: (name) => !name.startsWith('on'),
|
1052 |
+
_indexable: (name) => name !== 'events',
|
1053 |
+
hover: {
|
1054 |
+
_fallback: 'interaction'
|
1055 |
+
},
|
1056 |
+
interaction: {
|
1057 |
+
_scriptable: false,
|
1058 |
+
_indexable: false,
|
1059 |
+
}
|
1060 |
+
});
|
1061 |
+
|
1062 |
+
const PI = Math.PI;
|
1063 |
+
const TAU = 2 * PI;
|
1064 |
+
const PITAU = TAU + PI;
|
1065 |
+
const INFINITY = Number.POSITIVE_INFINITY;
|
1066 |
+
const RAD_PER_DEG = PI / 180;
|
1067 |
+
const HALF_PI = PI / 2;
|
1068 |
+
const QUARTER_PI = PI / 4;
|
1069 |
+
const TWO_THIRDS_PI = PI * 2 / 3;
|
1070 |
+
const log10 = Math.log10;
|
1071 |
+
const sign = Math.sign;
|
1072 |
+
function niceNum(range) {
|
1073 |
+
const roundedRange = Math.round(range);
|
1074 |
+
range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range;
|
1075 |
+
const niceRange = Math.pow(10, Math.floor(log10(range)));
|
1076 |
+
const fraction = range / niceRange;
|
1077 |
+
const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;
|
1078 |
+
return niceFraction * niceRange;
|
1079 |
+
}
|
1080 |
+
function _factorize(value) {
|
1081 |
+
const result = [];
|
1082 |
+
const sqrt = Math.sqrt(value);
|
1083 |
+
let i;
|
1084 |
+
for (i = 1; i < sqrt; i++) {
|
1085 |
+
if (value % i === 0) {
|
1086 |
+
result.push(i);
|
1087 |
+
result.push(value / i);
|
1088 |
+
}
|
1089 |
+
}
|
1090 |
+
if (sqrt === (sqrt | 0)) {
|
1091 |
+
result.push(sqrt);
|
1092 |
+
}
|
1093 |
+
result.sort((a, b) => a - b).pop();
|
1094 |
+
return result;
|
1095 |
+
}
|
1096 |
+
function isNumber(n) {
|
1097 |
+
return !isNaN(parseFloat(n)) && isFinite(n);
|
1098 |
+
}
|
1099 |
+
function almostEquals(x, y, epsilon) {
|
1100 |
+
return Math.abs(x - y) < epsilon;
|
1101 |
+
}
|
1102 |
+
function almostWhole(x, epsilon) {
|
1103 |
+
const rounded = Math.round(x);
|
1104 |
+
return ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x);
|
1105 |
+
}
|
1106 |
+
function _setMinAndMaxByKey(array, target, property) {
|
1107 |
+
let i, ilen, value;
|
1108 |
+
for (i = 0, ilen = array.length; i < ilen; i++) {
|
1109 |
+
value = array[i][property];
|
1110 |
+
if (!isNaN(value)) {
|
1111 |
+
target.min = Math.min(target.min, value);
|
1112 |
+
target.max = Math.max(target.max, value);
|
1113 |
+
}
|
1114 |
+
}
|
1115 |
+
}
|
1116 |
+
function toRadians(degrees) {
|
1117 |
+
return degrees * (PI / 180);
|
1118 |
+
}
|
1119 |
+
function toDegrees(radians) {
|
1120 |
+
return radians * (180 / PI);
|
1121 |
+
}
|
1122 |
+
function _decimalPlaces(x) {
|
1123 |
+
if (!isNumberFinite(x)) {
|
1124 |
+
return;
|
1125 |
+
}
|
1126 |
+
let e = 1;
|
1127 |
+
let p = 0;
|
1128 |
+
while (Math.round(x * e) / e !== x) {
|
1129 |
+
e *= 10;
|
1130 |
+
p++;
|
1131 |
+
}
|
1132 |
+
return p;
|
1133 |
+
}
|
1134 |
+
function getAngleFromPoint(centrePoint, anglePoint) {
|
1135 |
+
const distanceFromXCenter = anglePoint.x - centrePoint.x;
|
1136 |
+
const distanceFromYCenter = anglePoint.y - centrePoint.y;
|
1137 |
+
const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
|
1138 |
+
let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
|
1139 |
+
if (angle < (-0.5 * PI)) {
|
1140 |
+
angle += TAU;
|
1141 |
+
}
|
1142 |
+
return {
|
1143 |
+
angle,
|
1144 |
+
distance: radialDistanceFromCenter
|
1145 |
+
};
|
1146 |
+
}
|
1147 |
+
function distanceBetweenPoints(pt1, pt2) {
|
1148 |
+
return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
|
1149 |
+
}
|
1150 |
+
function _angleDiff(a, b) {
|
1151 |
+
return (a - b + PITAU) % TAU - PI;
|
1152 |
+
}
|
1153 |
+
function _normalizeAngle(a) {
|
1154 |
+
return (a % TAU + TAU) % TAU;
|
1155 |
+
}
|
1156 |
+
function _angleBetween(angle, start, end, sameAngleIsFullCircle) {
|
1157 |
+
const a = _normalizeAngle(angle);
|
1158 |
+
const s = _normalizeAngle(start);
|
1159 |
+
const e = _normalizeAngle(end);
|
1160 |
+
const angleToStart = _normalizeAngle(s - a);
|
1161 |
+
const angleToEnd = _normalizeAngle(e - a);
|
1162 |
+
const startToAngle = _normalizeAngle(a - s);
|
1163 |
+
const endToAngle = _normalizeAngle(a - e);
|
1164 |
+
return a === s || a === e || (sameAngleIsFullCircle && s === e)
|
1165 |
+
|| (angleToStart > angleToEnd && startToAngle < endToAngle);
|
1166 |
+
}
|
1167 |
+
function _limitValue(value, min, max) {
|
1168 |
+
return Math.max(min, Math.min(max, value));
|
1169 |
+
}
|
1170 |
+
function _int16Range(value) {
|
1171 |
+
return _limitValue(value, -32768, 32767);
|
1172 |
+
}
|
1173 |
+
function _isBetween(value, start, end, epsilon = 1e-6) {
|
1174 |
+
return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;
|
1175 |
+
}
|
1176 |
+
|
1177 |
+
function toFontString(font) {
|
1178 |
+
if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) {
|
1179 |
+
return null;
|
1180 |
+
}
|
1181 |
+
return (font.style ? font.style + ' ' : '')
|
1182 |
+
+ (font.weight ? font.weight + ' ' : '')
|
1183 |
+
+ font.size + 'px '
|
1184 |
+
+ font.family;
|
1185 |
+
}
|
1186 |
+
function _measureText(ctx, data, gc, longest, string) {
|
1187 |
+
let textWidth = data[string];
|
1188 |
+
if (!textWidth) {
|
1189 |
+
textWidth = data[string] = ctx.measureText(string).width;
|
1190 |
+
gc.push(string);
|
1191 |
+
}
|
1192 |
+
if (textWidth > longest) {
|
1193 |
+
longest = textWidth;
|
1194 |
+
}
|
1195 |
+
return longest;
|
1196 |
+
}
|
1197 |
+
function _longestText(ctx, font, arrayOfThings, cache) {
|
1198 |
+
cache = cache || {};
|
1199 |
+
let data = cache.data = cache.data || {};
|
1200 |
+
let gc = cache.garbageCollect = cache.garbageCollect || [];
|
1201 |
+
if (cache.font !== font) {
|
1202 |
+
data = cache.data = {};
|
1203 |
+
gc = cache.garbageCollect = [];
|
1204 |
+
cache.font = font;
|
1205 |
+
}
|
1206 |
+
ctx.save();
|
1207 |
+
ctx.font = font;
|
1208 |
+
let longest = 0;
|
1209 |
+
const ilen = arrayOfThings.length;
|
1210 |
+
let i, j, jlen, thing, nestedThing;
|
1211 |
+
for (i = 0; i < ilen; i++) {
|
1212 |
+
thing = arrayOfThings[i];
|
1213 |
+
if (thing !== undefined && thing !== null && isArray(thing) !== true) {
|
1214 |
+
longest = _measureText(ctx, data, gc, longest, thing);
|
1215 |
+
} else if (isArray(thing)) {
|
1216 |
+
for (j = 0, jlen = thing.length; j < jlen; j++) {
|
1217 |
+
nestedThing = thing[j];
|
1218 |
+
if (nestedThing !== undefined && nestedThing !== null && !isArray(nestedThing)) {
|
1219 |
+
longest = _measureText(ctx, data, gc, longest, nestedThing);
|
1220 |
}
|
1221 |
+
}
|
1222 |
+
}
|
1223 |
+
}
|
1224 |
+
ctx.restore();
|
1225 |
+
const gcLen = gc.length / 2;
|
1226 |
+
if (gcLen > arrayOfThings.length) {
|
1227 |
+
for (i = 0; i < gcLen; i++) {
|
1228 |
+
delete data[gc[i]];
|
1229 |
+
}
|
1230 |
+
gc.splice(0, gcLen);
|
1231 |
+
}
|
1232 |
+
return longest;
|
1233 |
+
}
|
1234 |
+
function _alignPixel(chart, pixel, width) {
|
1235 |
+
const devicePixelRatio = chart.currentDevicePixelRatio;
|
1236 |
+
const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0;
|
1237 |
+
return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth;
|
1238 |
+
}
|
1239 |
+
function clearCanvas(canvas, ctx) {
|
1240 |
+
ctx = ctx || canvas.getContext('2d');
|
1241 |
+
ctx.save();
|
1242 |
+
ctx.resetTransform();
|
1243 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
1244 |
+
ctx.restore();
|
1245 |
+
}
|
1246 |
+
function drawPoint(ctx, options, x, y) {
|
1247 |
+
let type, xOffset, yOffset, size, cornerRadius;
|
1248 |
+
const style = options.pointStyle;
|
1249 |
+
const rotation = options.rotation;
|
1250 |
+
const radius = options.radius;
|
1251 |
+
let rad = (rotation || 0) * RAD_PER_DEG;
|
1252 |
+
if (style && typeof style === 'object') {
|
1253 |
+
type = style.toString();
|
1254 |
+
if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
|
1255 |
+
ctx.save();
|
1256 |
+
ctx.translate(x, y);
|
1257 |
+
ctx.rotate(rad);
|
1258 |
+
ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);
|
1259 |
+
ctx.restore();
|
1260 |
+
return;
|
1261 |
+
}
|
1262 |
+
}
|
1263 |
+
if (isNaN(radius) || radius <= 0) {
|
1264 |
+
return;
|
1265 |
+
}
|
1266 |
+
ctx.beginPath();
|
1267 |
+
switch (style) {
|
1268 |
+
default:
|
1269 |
+
ctx.arc(x, y, radius, 0, TAU);
|
1270 |
+
ctx.closePath();
|
1271 |
+
break;
|
1272 |
+
case 'triangle':
|
1273 |
+
ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
|
1274 |
+
rad += TWO_THIRDS_PI;
|
1275 |
+
ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
|
1276 |
+
rad += TWO_THIRDS_PI;
|
1277 |
+
ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
|
1278 |
+
ctx.closePath();
|
1279 |
+
break;
|
1280 |
+
case 'rectRounded':
|
1281 |
+
cornerRadius = radius * 0.516;
|
1282 |
+
size = radius - cornerRadius;
|
1283 |
+
xOffset = Math.cos(rad + QUARTER_PI) * size;
|
1284 |
+
yOffset = Math.sin(rad + QUARTER_PI) * size;
|
1285 |
+
ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);
|
1286 |
+
ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad);
|
1287 |
+
ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI);
|
1288 |
+
ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);
|
1289 |
+
ctx.closePath();
|
1290 |
+
break;
|
1291 |
+
case 'rect':
|
1292 |
+
if (!rotation) {
|
1293 |
+
size = Math.SQRT1_2 * radius;
|
1294 |
+
ctx.rect(x - size, y - size, 2 * size, 2 * size);
|
1295 |
+
break;
|
1296 |
+
}
|
1297 |
+
rad += QUARTER_PI;
|
1298 |
+
case 'rectRot':
|
1299 |
+
xOffset = Math.cos(rad) * radius;
|
1300 |
+
yOffset = Math.sin(rad) * radius;
|
1301 |
+
ctx.moveTo(x - xOffset, y - yOffset);
|
1302 |
+
ctx.lineTo(x + yOffset, y - xOffset);
|
1303 |
+
ctx.lineTo(x + xOffset, y + yOffset);
|
1304 |
+
ctx.lineTo(x - yOffset, y + xOffset);
|
1305 |
+
ctx.closePath();
|
1306 |
+
break;
|
1307 |
+
case 'crossRot':
|
1308 |
+
rad += QUARTER_PI;
|
1309 |
+
case 'cross':
|
1310 |
+
xOffset = Math.cos(rad) * radius;
|
1311 |
+
yOffset = Math.sin(rad) * radius;
|
1312 |
+
ctx.moveTo(x - xOffset, y - yOffset);
|
1313 |
+
ctx.lineTo(x + xOffset, y + yOffset);
|
1314 |
+
ctx.moveTo(x + yOffset, y - xOffset);
|
1315 |
+
ctx.lineTo(x - yOffset, y + xOffset);
|
1316 |
+
break;
|
1317 |
+
case 'star':
|
1318 |
+
xOffset = Math.cos(rad) * radius;
|
1319 |
+
yOffset = Math.sin(rad) * radius;
|
1320 |
+
ctx.moveTo(x - xOffset, y - yOffset);
|
1321 |
+
ctx.lineTo(x + xOffset, y + yOffset);
|
1322 |
+
ctx.moveTo(x + yOffset, y - xOffset);
|
1323 |
+
ctx.lineTo(x - yOffset, y + xOffset);
|
1324 |
+
rad += QUARTER_PI;
|
1325 |
+
xOffset = Math.cos(rad) * radius;
|
1326 |
+
yOffset = Math.sin(rad) * radius;
|
1327 |
+
ctx.moveTo(x - xOffset, y - yOffset);
|
1328 |
+
ctx.lineTo(x + xOffset, y + yOffset);
|
1329 |
+
ctx.moveTo(x + yOffset, y - xOffset);
|
1330 |
+
ctx.lineTo(x - yOffset, y + xOffset);
|
1331 |
+
break;
|
1332 |
+
case 'line':
|
1333 |
+
xOffset = Math.cos(rad) * radius;
|
1334 |
+
yOffset = Math.sin(rad) * radius;
|
1335 |
+
ctx.moveTo(x - xOffset, y - yOffset);
|
1336 |
+
ctx.lineTo(x + xOffset, y + yOffset);
|
1337 |
+
break;
|
1338 |
+
case 'dash':
|
1339 |
+
ctx.moveTo(x, y);
|
1340 |
+
ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius);
|
1341 |
+
break;
|
1342 |
+
}
|
1343 |
+
ctx.fill();
|
1344 |
+
if (options.borderWidth > 0) {
|
1345 |
+
ctx.stroke();
|
1346 |
+
}
|
1347 |
+
}
|
1348 |
+
function _isPointInArea(point, area, margin) {
|
1349 |
+
margin = margin || 0.5;
|
1350 |
+
return !area || (point && point.x > area.left - margin && point.x < area.right + margin &&
|
1351 |
+
point.y > area.top - margin && point.y < area.bottom + margin);
|
1352 |
+
}
|
1353 |
+
function clipArea(ctx, area) {
|
1354 |
+
ctx.save();
|
1355 |
+
ctx.beginPath();
|
1356 |
+
ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
|
1357 |
+
ctx.clip();
|
1358 |
+
}
|
1359 |
+
function unclipArea(ctx) {
|
1360 |
+
ctx.restore();
|
1361 |
+
}
|
1362 |
+
function _steppedLineTo(ctx, previous, target, flip, mode) {
|
1363 |
+
if (!previous) {
|
1364 |
+
return ctx.lineTo(target.x, target.y);
|
1365 |
+
}
|
1366 |
+
if (mode === 'middle') {
|
1367 |
+
const midpoint = (previous.x + target.x) / 2.0;
|
1368 |
+
ctx.lineTo(midpoint, previous.y);
|
1369 |
+
ctx.lineTo(midpoint, target.y);
|
1370 |
+
} else if (mode === 'after' !== !!flip) {
|
1371 |
+
ctx.lineTo(previous.x, target.y);
|
1372 |
+
} else {
|
1373 |
+
ctx.lineTo(target.x, previous.y);
|
1374 |
+
}
|
1375 |
+
ctx.lineTo(target.x, target.y);
|
1376 |
+
}
|
1377 |
+
function _bezierCurveTo(ctx, previous, target, flip) {
|
1378 |
+
if (!previous) {
|
1379 |
+
return ctx.lineTo(target.x, target.y);
|
1380 |
+
}
|
1381 |
+
ctx.bezierCurveTo(
|
1382 |
+
flip ? previous.cp1x : previous.cp2x,
|
1383 |
+
flip ? previous.cp1y : previous.cp2y,
|
1384 |
+
flip ? target.cp2x : target.cp1x,
|
1385 |
+
flip ? target.cp2y : target.cp1y,
|
1386 |
+
target.x,
|
1387 |
+
target.y);
|
1388 |
+
}
|
1389 |
+
function renderText(ctx, text, x, y, font, opts = {}) {
|
1390 |
+
const lines = isArray(text) ? text : [text];
|
1391 |
+
const stroke = opts.strokeWidth > 0 && opts.strokeColor !== '';
|
1392 |
+
let i, line;
|
1393 |
+
ctx.save();
|
1394 |
+
ctx.font = font.string;
|
1395 |
+
setRenderOpts(ctx, opts);
|
1396 |
+
for (i = 0; i < lines.length; ++i) {
|
1397 |
+
line = lines[i];
|
1398 |
+
if (stroke) {
|
1399 |
+
if (opts.strokeColor) {
|
1400 |
+
ctx.strokeStyle = opts.strokeColor;
|
1401 |
+
}
|
1402 |
+
if (!isNullOrUndef(opts.strokeWidth)) {
|
1403 |
+
ctx.lineWidth = opts.strokeWidth;
|
1404 |
+
}
|
1405 |
+
ctx.strokeText(line, x, y, opts.maxWidth);
|
1406 |
+
}
|
1407 |
+
ctx.fillText(line, x, y, opts.maxWidth);
|
1408 |
+
decorateText(ctx, x, y, line, opts);
|
1409 |
+
y += font.lineHeight;
|
1410 |
+
}
|
1411 |
+
ctx.restore();
|
1412 |
+
}
|
1413 |
+
function setRenderOpts(ctx, opts) {
|
1414 |
+
if (opts.translation) {
|
1415 |
+
ctx.translate(opts.translation[0], opts.translation[1]);
|
1416 |
+
}
|
1417 |
+
if (!isNullOrUndef(opts.rotation)) {
|
1418 |
+
ctx.rotate(opts.rotation);
|
1419 |
+
}
|
1420 |
+
if (opts.color) {
|
1421 |
+
ctx.fillStyle = opts.color;
|
1422 |
+
}
|
1423 |
+
if (opts.textAlign) {
|
1424 |
+
ctx.textAlign = opts.textAlign;
|
1425 |
+
}
|
1426 |
+
if (opts.textBaseline) {
|
1427 |
+
ctx.textBaseline = opts.textBaseline;
|
1428 |
+
}
|
1429 |
+
}
|
1430 |
+
function decorateText(ctx, x, y, line, opts) {
|
1431 |
+
if (opts.strikethrough || opts.underline) {
|
1432 |
+
const metrics = ctx.measureText(line);
|
1433 |
+
const left = x - metrics.actualBoundingBoxLeft;
|
1434 |
+
const right = x + metrics.actualBoundingBoxRight;
|
1435 |
+
const top = y - metrics.actualBoundingBoxAscent;
|
1436 |
+
const bottom = y + metrics.actualBoundingBoxDescent;
|
1437 |
+
const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;
|
1438 |
+
ctx.strokeStyle = ctx.fillStyle;
|
1439 |
+
ctx.beginPath();
|
1440 |
+
ctx.lineWidth = opts.decorationWidth || 2;
|
1441 |
+
ctx.moveTo(left, yDecoration);
|
1442 |
+
ctx.lineTo(right, yDecoration);
|
1443 |
+
ctx.stroke();
|
1444 |
+
}
|
1445 |
+
}
|
1446 |
+
function addRoundedRectPath(ctx, rect) {
|
1447 |
+
const {x, y, w, h, radius} = rect;
|
1448 |
+
ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, -HALF_PI, PI, true);
|
1449 |
+
ctx.lineTo(x, y + h - radius.bottomLeft);
|
1450 |
+
ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true);
|
1451 |
+
ctx.lineTo(x + w - radius.bottomRight, y + h);
|
1452 |
+
ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true);
|
1453 |
+
ctx.lineTo(x + w, y + radius.topRight);
|
1454 |
+
ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI, true);
|
1455 |
+
ctx.lineTo(x + radius.topLeft, y);
|
1456 |
+
}
|
1457 |
+
|
1458 |
+
function _lookup(table, value, cmp) {
|
1459 |
+
cmp = cmp || ((index) => table[index] < value);
|
1460 |
+
let hi = table.length - 1;
|
1461 |
+
let lo = 0;
|
1462 |
+
let mid;
|
1463 |
+
while (hi - lo > 1) {
|
1464 |
+
mid = (lo + hi) >> 1;
|
1465 |
+
if (cmp(mid)) {
|
1466 |
+
lo = mid;
|
1467 |
+
} else {
|
1468 |
+
hi = mid;
|
1469 |
+
}
|
1470 |
+
}
|
1471 |
+
return {lo, hi};
|
1472 |
+
}
|
1473 |
+
const _lookupByKey = (table, key, value) =>
|
1474 |
+
_lookup(table, value, index => table[index][key] < value);
|
1475 |
+
const _rlookupByKey = (table, key, value) =>
|
1476 |
+
_lookup(table, value, index => table[index][key] >= value);
|
1477 |
+
function _filterBetween(values, min, max) {
|
1478 |
+
let start = 0;
|
1479 |
+
let end = values.length;
|
1480 |
+
while (start < end && values[start] < min) {
|
1481 |
+
start++;
|
1482 |
+
}
|
1483 |
+
while (end > start && values[end - 1] > max) {
|
1484 |
+
end--;
|
1485 |
+
}
|
1486 |
+
return start > 0 || end < values.length
|
1487 |
+
? values.slice(start, end)
|
1488 |
+
: values;
|
1489 |
+
}
|
1490 |
+
const arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
|
1491 |
+
function listenArrayEvents(array, listener) {
|
1492 |
+
if (array._chartjs) {
|
1493 |
+
array._chartjs.listeners.push(listener);
|
1494 |
+
return;
|
1495 |
+
}
|
1496 |
+
Object.defineProperty(array, '_chartjs', {
|
1497 |
+
configurable: true,
|
1498 |
+
enumerable: false,
|
1499 |
+
value: {
|
1500 |
+
listeners: [listener]
|
1501 |
+
}
|
1502 |
+
});
|
1503 |
+
arrayEvents.forEach((key) => {
|
1504 |
+
const method = '_onData' + _capitalize(key);
|
1505 |
+
const base = array[key];
|
1506 |
+
Object.defineProperty(array, key, {
|
1507 |
+
configurable: true,
|
1508 |
+
enumerable: false,
|
1509 |
+
value(...args) {
|
1510 |
+
const res = base.apply(this, args);
|
1511 |
+
array._chartjs.listeners.forEach((object) => {
|
1512 |
+
if (typeof object[method] === 'function') {
|
1513 |
+
object[method](...args);
|
1514 |
+
}
|
1515 |
+
});
|
1516 |
+
return res;
|
1517 |
+
}
|
1518 |
+
});
|
1519 |
+
});
|
1520 |
+
}
|
1521 |
+
function unlistenArrayEvents(array, listener) {
|
1522 |
+
const stub = array._chartjs;
|
1523 |
+
if (!stub) {
|
1524 |
+
return;
|
1525 |
+
}
|
1526 |
+
const listeners = stub.listeners;
|
1527 |
+
const index = listeners.indexOf(listener);
|
1528 |
+
if (index !== -1) {
|
1529 |
+
listeners.splice(index, 1);
|
1530 |
+
}
|
1531 |
+
if (listeners.length > 0) {
|
1532 |
+
return;
|
1533 |
+
}
|
1534 |
+
arrayEvents.forEach((key) => {
|
1535 |
+
delete array[key];
|
1536 |
+
});
|
1537 |
+
delete array._chartjs;
|
1538 |
+
}
|
1539 |
+
function _arrayUnique(items) {
|
1540 |
+
const set = new Set();
|
1541 |
+
let i, ilen;
|
1542 |
+
for (i = 0, ilen = items.length; i < ilen; ++i) {
|
1543 |
+
set.add(items[i]);
|
1544 |
+
}
|
1545 |
+
if (set.size === ilen) {
|
1546 |
+
return items;
|
1547 |
+
}
|
1548 |
+
return Array.from(set);
|
1549 |
+
}
|
1550 |
+
|
1551 |
+
function _isDomSupported() {
|
1552 |
+
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
1553 |
+
}
|
1554 |
+
function _getParentNode(domNode) {
|
1555 |
+
let parent = domNode.parentNode;
|
1556 |
+
if (parent && parent.toString() === '[object ShadowRoot]') {
|
1557 |
+
parent = parent.host;
|
1558 |
+
}
|
1559 |
+
return parent;
|
1560 |
+
}
|
1561 |
+
function parseMaxStyle(styleValue, node, parentProperty) {
|
1562 |
+
let valueInPixels;
|
1563 |
+
if (typeof styleValue === 'string') {
|
1564 |
+
valueInPixels = parseInt(styleValue, 10);
|
1565 |
+
if (styleValue.indexOf('%') !== -1) {
|
1566 |
+
valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
|
1567 |
+
}
|
1568 |
+
} else {
|
1569 |
+
valueInPixels = styleValue;
|
1570 |
+
}
|
1571 |
+
return valueInPixels;
|
1572 |
+
}
|
1573 |
+
const getComputedStyle = (element) => window.getComputedStyle(element, null);
|
1574 |
+
function getStyle(el, property) {
|
1575 |
+
return getComputedStyle(el).getPropertyValue(property);
|
1576 |
+
}
|
1577 |
+
const positions = ['top', 'right', 'bottom', 'left'];
|
1578 |
+
function getPositionedStyle(styles, style, suffix) {
|
1579 |
+
const result = {};
|
1580 |
+
suffix = suffix ? '-' + suffix : '';
|
1581 |
+
for (let i = 0; i < 4; i++) {
|
1582 |
+
const pos = positions[i];
|
1583 |
+
result[pos] = parseFloat(styles[style + '-' + pos + suffix]) || 0;
|
1584 |
+
}
|
1585 |
+
result.width = result.left + result.right;
|
1586 |
+
result.height = result.top + result.bottom;
|
1587 |
+
return result;
|
1588 |
+
}
|
1589 |
+
const useOffsetPos = (x, y, target) => (x > 0 || y > 0) && (!target || !target.shadowRoot);
|
1590 |
+
function getCanvasPosition(evt, canvas) {
|
1591 |
+
const e = evt.native || evt;
|
1592 |
+
const touches = e.touches;
|
1593 |
+
const source = touches && touches.length ? touches[0] : e;
|
1594 |
+
const {offsetX, offsetY} = source;
|
1595 |
+
let box = false;
|
1596 |
+
let x, y;
|
1597 |
+
if (useOffsetPos(offsetX, offsetY, e.target)) {
|
1598 |
+
x = offsetX;
|
1599 |
+
y = offsetY;
|
1600 |
+
} else {
|
1601 |
+
const rect = canvas.getBoundingClientRect();
|
1602 |
+
x = source.clientX - rect.left;
|
1603 |
+
y = source.clientY - rect.top;
|
1604 |
+
box = true;
|
1605 |
+
}
|
1606 |
+
return {x, y, box};
|
1607 |
+
}
|
1608 |
+
function getRelativePosition$1(evt, chart) {
|
1609 |
+
const {canvas, currentDevicePixelRatio} = chart;
|
1610 |
+
const style = getComputedStyle(canvas);
|
1611 |
+
const borderBox = style.boxSizing === 'border-box';
|
1612 |
+
const paddings = getPositionedStyle(style, 'padding');
|
1613 |
+
const borders = getPositionedStyle(style, 'border', 'width');
|
1614 |
+
const {x, y, box} = getCanvasPosition(evt, canvas);
|
1615 |
+
const xOffset = paddings.left + (box && borders.left);
|
1616 |
+
const yOffset = paddings.top + (box && borders.top);
|
1617 |
+
let {width, height} = chart;
|
1618 |
+
if (borderBox) {
|
1619 |
+
width -= paddings.width + borders.width;
|
1620 |
+
height -= paddings.height + borders.height;
|
1621 |
+
}
|
1622 |
+
return {
|
1623 |
+
x: Math.round((x - xOffset) / width * canvas.width / currentDevicePixelRatio),
|
1624 |
+
y: Math.round((y - yOffset) / height * canvas.height / currentDevicePixelRatio)
|
1625 |
+
};
|
1626 |
+
}
|
1627 |
+
function getContainerSize(canvas, width, height) {
|
1628 |
+
let maxWidth, maxHeight;
|
1629 |
+
if (width === undefined || height === undefined) {
|
1630 |
+
const container = _getParentNode(canvas);
|
1631 |
+
if (!container) {
|
1632 |
+
width = canvas.clientWidth;
|
1633 |
+
height = canvas.clientHeight;
|
1634 |
+
} else {
|
1635 |
+
const rect = container.getBoundingClientRect();
|
1636 |
+
const containerStyle = getComputedStyle(container);
|
1637 |
+
const containerBorder = getPositionedStyle(containerStyle, 'border', 'width');
|
1638 |
+
const containerPadding = getPositionedStyle(containerStyle, 'padding');
|
1639 |
+
width = rect.width - containerPadding.width - containerBorder.width;
|
1640 |
+
height = rect.height - containerPadding.height - containerBorder.height;
|
1641 |
+
maxWidth = parseMaxStyle(containerStyle.maxWidth, container, 'clientWidth');
|
1642 |
+
maxHeight = parseMaxStyle(containerStyle.maxHeight, container, 'clientHeight');
|
1643 |
+
}
|
1644 |
+
}
|
1645 |
+
return {
|
1646 |
+
width,
|
1647 |
+
height,
|
1648 |
+
maxWidth: maxWidth || INFINITY,
|
1649 |
+
maxHeight: maxHeight || INFINITY
|
1650 |
+
};
|
1651 |
+
}
|
1652 |
+
const round1 = v => Math.round(v * 10) / 10;
|
1653 |
+
function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) {
|
1654 |
+
const style = getComputedStyle(canvas);
|
1655 |
+
const margins = getPositionedStyle(style, 'margin');
|
1656 |
+
const maxWidth = parseMaxStyle(style.maxWidth, canvas, 'clientWidth') || INFINITY;
|
1657 |
+
const maxHeight = parseMaxStyle(style.maxHeight, canvas, 'clientHeight') || INFINITY;
|
1658 |
+
const containerSize = getContainerSize(canvas, bbWidth, bbHeight);
|
1659 |
+
let {width, height} = containerSize;
|
1660 |
+
if (style.boxSizing === 'content-box') {
|
1661 |
+
const borders = getPositionedStyle(style, 'border', 'width');
|
1662 |
+
const paddings = getPositionedStyle(style, 'padding');
|
1663 |
+
width -= paddings.width + borders.width;
|
1664 |
+
height -= paddings.height + borders.height;
|
1665 |
+
}
|
1666 |
+
width = Math.max(0, width - margins.width);
|
1667 |
+
height = Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height - margins.height);
|
1668 |
+
width = round1(Math.min(width, maxWidth, containerSize.maxWidth));
|
1669 |
+
height = round1(Math.min(height, maxHeight, containerSize.maxHeight));
|
1670 |
+
if (width && !height) {
|
1671 |
+
height = round1(width / 2);
|
1672 |
+
}
|
1673 |
+
return {
|
1674 |
+
width,
|
1675 |
+
height
|
1676 |
+
};
|
1677 |
+
}
|
1678 |
+
function retinaScale(chart, forceRatio, forceStyle) {
|
1679 |
+
const pixelRatio = forceRatio || 1;
|
1680 |
+
const deviceHeight = Math.floor(chart.height * pixelRatio);
|
1681 |
+
const deviceWidth = Math.floor(chart.width * pixelRatio);
|
1682 |
+
chart.height = deviceHeight / pixelRatio;
|
1683 |
+
chart.width = deviceWidth / pixelRatio;
|
1684 |
+
const canvas = chart.canvas;
|
1685 |
+
if (canvas.style && (forceStyle || (!canvas.style.height && !canvas.style.width))) {
|
1686 |
+
canvas.style.height = `${chart.height}px`;
|
1687 |
+
canvas.style.width = `${chart.width}px`;
|
1688 |
+
}
|
1689 |
+
if (chart.currentDevicePixelRatio !== pixelRatio
|
1690 |
+
|| canvas.height !== deviceHeight
|
1691 |
+
|| canvas.width !== deviceWidth) {
|
1692 |
+
chart.currentDevicePixelRatio = pixelRatio;
|
1693 |
+
canvas.height = deviceHeight;
|
1694 |
+
canvas.width = deviceWidth;
|
1695 |
+
chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
|
1696 |
+
return true;
|
1697 |
+
}
|
1698 |
+
return false;
|
1699 |
+
}
|
1700 |
+
const supportsEventListenerOptions = (function() {
|
1701 |
+
let passiveSupported = false;
|
1702 |
+
try {
|
1703 |
+
const options = {
|
1704 |
+
get passive() {
|
1705 |
+
passiveSupported = true;
|
1706 |
+
return false;
|
1707 |
+
}
|
1708 |
+
};
|
1709 |
+
window.addEventListener('test', null, options);
|
1710 |
+
window.removeEventListener('test', null, options);
|
1711 |
+
} catch (e) {
|
1712 |
+
}
|
1713 |
+
return passiveSupported;
|
1714 |
+
}());
|
1715 |
+
function readUsedSize(element, property) {
|
1716 |
+
const value = getStyle(element, property);
|
1717 |
+
const matches = value && value.match(/^(\d+)(\.\d+)?px$/);
|
1718 |
+
return matches ? +matches[1] : undefined;
|
1719 |
+
}
|
1720 |
+
|
1721 |
+
function getRelativePosition(e, chart) {
|
1722 |
+
if ('native' in e) {
|
1723 |
+
return {
|
1724 |
+
x: e.x,
|
1725 |
+
y: e.y
|
1726 |
+
};
|
1727 |
+
}
|
1728 |
+
return getRelativePosition$1(e, chart);
|
1729 |
+
}
|
1730 |
+
function evaluateAllVisibleItems(chart, handler) {
|
1731 |
+
const metasets = chart.getSortedVisibleDatasetMetas();
|
1732 |
+
let index, data, element;
|
1733 |
+
for (let i = 0, ilen = metasets.length; i < ilen; ++i) {
|
1734 |
+
({index, data} = metasets[i]);
|
1735 |
+
for (let j = 0, jlen = data.length; j < jlen; ++j) {
|
1736 |
+
element = data[j];
|
1737 |
+
if (!element.skip) {
|
1738 |
+
handler(element, index, j);
|
1739 |
+
}
|
1740 |
+
}
|
1741 |
+
}
|
1742 |
+
}
|
1743 |
+
function binarySearch(metaset, axis, value, intersect) {
|
1744 |
+
const {controller, data, _sorted} = metaset;
|
1745 |
+
const iScale = controller._cachedMeta.iScale;
|
1746 |
+
if (iScale && axis === iScale.axis && axis !== 'r' && _sorted && data.length) {
|
1747 |
+
const lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey;
|
1748 |
+
if (!intersect) {
|
1749 |
+
return lookupMethod(data, axis, value);
|
1750 |
+
} else if (controller._sharedOptions) {
|
1751 |
+
const el = data[0];
|
1752 |
+
const range = typeof el.getRange === 'function' && el.getRange(axis);
|
1753 |
+
if (range) {
|
1754 |
+
const start = lookupMethod(data, axis, value - range);
|
1755 |
+
const end = lookupMethod(data, axis, value + range);
|
1756 |
+
return {lo: start.lo, hi: end.hi};
|
1757 |
+
}
|
1758 |
+
}
|
1759 |
+
}
|
1760 |
+
return {lo: 0, hi: data.length - 1};
|
1761 |
+
}
|
1762 |
+
function optimizedEvaluateItems(chart, axis, position, handler, intersect) {
|
1763 |
+
const metasets = chart.getSortedVisibleDatasetMetas();
|
1764 |
+
const value = position[axis];
|
1765 |
+
for (let i = 0, ilen = metasets.length; i < ilen; ++i) {
|
1766 |
+
const {index, data} = metasets[i];
|
1767 |
+
const {lo, hi} = binarySearch(metasets[i], axis, value, intersect);
|
1768 |
+
for (let j = lo; j <= hi; ++j) {
|
1769 |
+
const element = data[j];
|
1770 |
+
if (!element.skip) {
|
1771 |
+
handler(element, index, j);
|
1772 |
+
}
|
1773 |
+
}
|
1774 |
+
}
|
1775 |
+
}
|
1776 |
+
function getDistanceMetricForAxis(axis) {
|
1777 |
+
const useX = axis.indexOf('x') !== -1;
|
1778 |
+
const useY = axis.indexOf('y') !== -1;
|
1779 |
+
return function(pt1, pt2) {
|
1780 |
+
const deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;
|
1781 |
+
const deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;
|
1782 |
+
return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
|
1783 |
+
};
|
1784 |
+
}
|
1785 |
+
function getIntersectItems(chart, position, axis, useFinalPosition) {
|
1786 |
+
const items = [];
|
1787 |
+
if (!_isPointInArea(position, chart.chartArea, chart._minPadding)) {
|
1788 |
+
return items;
|
1789 |
+
}
|
1790 |
+
const evaluationFunc = function(element, datasetIndex, index) {
|
1791 |
+
if (element.inRange(position.x, position.y, useFinalPosition)) {
|
1792 |
+
items.push({element, datasetIndex, index});
|
1793 |
+
}
|
1794 |
+
};
|
1795 |
+
optimizedEvaluateItems(chart, axis, position, evaluationFunc, true);
|
1796 |
+
return items;
|
1797 |
+
}
|
1798 |
+
function getNearestRadialItems(chart, position, axis, useFinalPosition) {
|
1799 |
+
let items = [];
|
1800 |
+
function evaluationFunc(element, datasetIndex, index) {
|
1801 |
+
const {startAngle, endAngle} = element.getProps(['startAngle', 'endAngle'], useFinalPosition);
|
1802 |
+
const {angle} = getAngleFromPoint(element, {x: position.x, y: position.y});
|
1803 |
+
if (_angleBetween(angle, startAngle, endAngle)) {
|
1804 |
+
items.push({element, datasetIndex, index});
|
1805 |
+
}
|
1806 |
+
}
|
1807 |
+
optimizedEvaluateItems(chart, axis, position, evaluationFunc);
|
1808 |
+
return items;
|
1809 |
+
}
|
1810 |
+
function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition) {
|
1811 |
+
let items = [];
|
1812 |
+
const distanceMetric = getDistanceMetricForAxis(axis);
|
1813 |
+
let minDistance = Number.POSITIVE_INFINITY;
|
1814 |
+
function evaluationFunc(element, datasetIndex, index) {
|
1815 |
+
const inRange = element.inRange(position.x, position.y, useFinalPosition);
|
1816 |
+
if (intersect && !inRange) {
|
1817 |
+
return;
|
1818 |
+
}
|
1819 |
+
const center = element.getCenterPoint(useFinalPosition);
|
1820 |
+
const pointInArea = _isPointInArea(center, chart.chartArea, chart._minPadding);
|
1821 |
+
if (!pointInArea && !inRange) {
|
1822 |
+
return;
|
1823 |
+
}
|
1824 |
+
const distance = distanceMetric(position, center);
|
1825 |
+
if (distance < minDistance) {
|
1826 |
+
items = [{element, datasetIndex, index}];
|
1827 |
+
minDistance = distance;
|
1828 |
+
} else if (distance === minDistance) {
|
1829 |
+
items.push({element, datasetIndex, index});
|
1830 |
+
}
|
1831 |
+
}
|
1832 |
+
optimizedEvaluateItems(chart, axis, position, evaluationFunc);
|
1833 |
+
return items;
|
1834 |
+
}
|
1835 |
+
function getNearestItems(chart, position, axis, intersect, useFinalPosition) {
|
1836 |
+
if (!_isPointInArea(position, chart.chartArea, chart._minPadding)) {
|
1837 |
+
return [];
|
1838 |
+
}
|
1839 |
+
return axis === 'r' && !intersect
|
1840 |
+
? getNearestRadialItems(chart, position, axis, useFinalPosition)
|
1841 |
+
: getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition);
|
1842 |
+
}
|
1843 |
+
function getAxisItems(chart, e, options, useFinalPosition) {
|
1844 |
+
const position = getRelativePosition(e, chart);
|
1845 |
+
const items = [];
|
1846 |
+
const axis = options.axis;
|
1847 |
+
const rangeMethod = axis === 'x' ? 'inXRange' : 'inYRange';
|
1848 |
+
let intersectsItem = false;
|
1849 |
+
evaluateAllVisibleItems(chart, (element, datasetIndex, index) => {
|
1850 |
+
if (element[rangeMethod](position[axis], useFinalPosition)) {
|
1851 |
+
items.push({element, datasetIndex, index});
|
1852 |
+
}
|
1853 |
+
if (element.inRange(position.x, position.y, useFinalPosition)) {
|
1854 |
+
intersectsItem = true;
|
1855 |
+
}
|
1856 |
+
});
|
1857 |
+
if (options.intersect && !intersectsItem) {
|
1858 |
+
return [];
|
1859 |
+
}
|
1860 |
+
return items;
|
1861 |
+
}
|
1862 |
+
var Interaction = {
|
1863 |
+
modes: {
|
1864 |
+
index(chart, e, options, useFinalPosition) {
|
1865 |
+
const position = getRelativePosition(e, chart);
|
1866 |
+
const axis = options.axis || 'x';
|
1867 |
+
const items = options.intersect
|
1868 |
+
? getIntersectItems(chart, position, axis, useFinalPosition)
|
1869 |
+
: getNearestItems(chart, position, axis, false, useFinalPosition);
|
1870 |
+
const elements = [];
|
1871 |
+
if (!items.length) {
|
1872 |
+
return [];
|
1873 |
+
}
|
1874 |
+
chart.getSortedVisibleDatasetMetas().forEach((meta) => {
|
1875 |
+
const index = items[0].index;
|
1876 |
+
const element = meta.data[index];
|
1877 |
+
if (element && !element.skip) {
|
1878 |
+
elements.push({element, datasetIndex: meta.index, index});
|
1879 |
+
}
|
1880 |
+
});
|
1881 |
+
return elements;
|
1882 |
},
|
1883 |
+
dataset(chart, e, options, useFinalPosition) {
|
1884 |
+
const position = getRelativePosition(e, chart);
|
1885 |
+
const axis = options.axis || 'xy';
|
1886 |
+
let items = options.intersect
|
1887 |
+
? getIntersectItems(chart, position, axis, useFinalPosition) :
|
1888 |
+
getNearestItems(chart, position, axis, false, useFinalPosition);
|
1889 |
+
if (items.length > 0) {
|
1890 |
+
const datasetIndex = items[0].datasetIndex;
|
1891 |
+
const data = chart.getDatasetMeta(datasetIndex).data;
|
1892 |
+
items = [];
|
1893 |
+
for (let i = 0; i < data.length; ++i) {
|
1894 |
+
items.push({element: data[i], datasetIndex, index: i});
|
1895 |
}
|
1896 |
+
}
|
1897 |
+
return items;
|
1898 |
},
|
1899 |
+
point(chart, e, options, useFinalPosition) {
|
1900 |
+
const position = getRelativePosition(e, chart);
|
1901 |
+
const axis = options.axis || 'xy';
|
1902 |
+
return getIntersectItems(chart, position, axis, useFinalPosition);
|
1903 |
},
|
1904 |
+
nearest(chart, e, options, useFinalPosition) {
|
1905 |
+
const position = getRelativePosition(e, chart);
|
1906 |
+
const axis = options.axis || 'xy';
|
1907 |
+
return getNearestItems(chart, position, axis, options.intersect, useFinalPosition);
|
1908 |
},
|
1909 |
+
x(chart, e, options, useFinalPosition) {
|
1910 |
+
return getAxisItems(chart, e, {axis: 'x', intersect: options.intersect}, useFinalPosition);
|
1911 |
},
|
1912 |
+
y(chart, e, options, useFinalPosition) {
|
1913 |
+
return getAxisItems(chart, e, {axis: 'y', intersect: options.intersect}, useFinalPosition);
|
1914 |
+
}
|
1915 |
+
}
|
1916 |
+
};
|
1917 |
+
|
1918 |
+
const LINE_HEIGHT = new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);
|
1919 |
+
const FONT_STYLE = new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);
|
1920 |
+
function toLineHeight(value, size) {
|
1921 |
+
const matches = ('' + value).match(LINE_HEIGHT);
|
1922 |
+
if (!matches || matches[1] === 'normal') {
|
1923 |
+
return size * 1.2;
|
1924 |
+
}
|
1925 |
+
value = +matches[2];
|
1926 |
+
switch (matches[3]) {
|
1927 |
+
case 'px':
|
1928 |
+
return value;
|
1929 |
+
case '%':
|
1930 |
+
value /= 100;
|
1931 |
+
break;
|
1932 |
+
}
|
1933 |
+
return size * value;
|
1934 |
+
}
|
1935 |
+
const numberOrZero = v => +v || 0;
|
1936 |
+
function _readValueToProps(value, props) {
|
1937 |
+
const ret = {};
|
1938 |
+
const objProps = isObject(props);
|
1939 |
+
const keys = objProps ? Object.keys(props) : props;
|
1940 |
+
const read = isObject(value)
|
1941 |
+
? objProps
|
1942 |
+
? prop => valueOrDefault(value[prop], value[props[prop]])
|
1943 |
+
: prop => value[prop]
|
1944 |
+
: () => value;
|
1945 |
+
for (const prop of keys) {
|
1946 |
+
ret[prop] = numberOrZero(read(prop));
|
1947 |
+
}
|
1948 |
+
return ret;
|
1949 |
+
}
|
1950 |
+
function toTRBL(value) {
|
1951 |
+
return _readValueToProps(value, {top: 'y', right: 'x', bottom: 'y', left: 'x'});
|
1952 |
+
}
|
1953 |
+
function toTRBLCorners(value) {
|
1954 |
+
return _readValueToProps(value, ['topLeft', 'topRight', 'bottomLeft', 'bottomRight']);
|
1955 |
+
}
|
1956 |
+
function toPadding(value) {
|
1957 |
+
const obj = toTRBL(value);
|
1958 |
+
obj.width = obj.left + obj.right;
|
1959 |
+
obj.height = obj.top + obj.bottom;
|
1960 |
+
return obj;
|
1961 |
+
}
|
1962 |
+
function toFont(options, fallback) {
|
1963 |
+
options = options || {};
|
1964 |
+
fallback = fallback || defaults.font;
|
1965 |
+
let size = valueOrDefault(options.size, fallback.size);
|
1966 |
+
if (typeof size === 'string') {
|
1967 |
+
size = parseInt(size, 10);
|
1968 |
+
}
|
1969 |
+
let style = valueOrDefault(options.style, fallback.style);
|
1970 |
+
if (style && !('' + style).match(FONT_STYLE)) {
|
1971 |
+
console.warn('Invalid font style specified: "' + style + '"');
|
1972 |
+
style = '';
|
1973 |
+
}
|
1974 |
+
const font = {
|
1975 |
+
family: valueOrDefault(options.family, fallback.family),
|
1976 |
+
lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size),
|
1977 |
+
size,
|
1978 |
+
style,
|
1979 |
+
weight: valueOrDefault(options.weight, fallback.weight),
|
1980 |
+
string: ''
|
1981 |
+
};
|
1982 |
+
font.string = toFontString(font);
|
1983 |
+
return font;
|
1984 |
+
}
|
1985 |
+
function resolve(inputs, context, index, info) {
|
1986 |
+
let cacheable = true;
|
1987 |
+
let i, ilen, value;
|
1988 |
+
for (i = 0, ilen = inputs.length; i < ilen; ++i) {
|
1989 |
+
value = inputs[i];
|
1990 |
+
if (value === undefined) {
|
1991 |
+
continue;
|
1992 |
+
}
|
1993 |
+
if (context !== undefined && typeof value === 'function') {
|
1994 |
+
value = value(context);
|
1995 |
+
cacheable = false;
|
1996 |
+
}
|
1997 |
+
if (index !== undefined && isArray(value)) {
|
1998 |
+
value = value[index % value.length];
|
1999 |
+
cacheable = false;
|
2000 |
+
}
|
2001 |
+
if (value !== undefined) {
|
2002 |
+
if (info && !cacheable) {
|
2003 |
+
info.cacheable = false;
|
2004 |
+
}
|
2005 |
+
return value;
|
2006 |
+
}
|
2007 |
+
}
|
2008 |
+
}
|
2009 |
+
function _addGrace(minmax, grace, beginAtZero) {
|
2010 |
+
const {min, max} = minmax;
|
2011 |
+
const change = toDimension(grace, (max - min) / 2);
|
2012 |
+
const keepZero = (value, add) => beginAtZero && value === 0 ? 0 : value + add;
|
2013 |
+
return {
|
2014 |
+
min: keepZero(min, -Math.abs(change)),
|
2015 |
+
max: keepZero(max, change)
|
2016 |
+
};
|
2017 |
+
}
|
2018 |
+
function createContext(parentContext, context) {
|
2019 |
+
return Object.assign(Object.create(parentContext), context);
|
2020 |
+
}
|
2021 |
+
|
2022 |
+
const STATIC_POSITIONS = ['left', 'top', 'right', 'bottom'];
|
2023 |
+
function filterByPosition(array, position) {
|
2024 |
+
return array.filter(v => v.pos === position);
|
2025 |
+
}
|
2026 |
+
function filterDynamicPositionByAxis(array, axis) {
|
2027 |
+
return array.filter(v => STATIC_POSITIONS.indexOf(v.pos) === -1 && v.box.axis === axis);
|
2028 |
+
}
|
2029 |
+
function sortByWeight(array, reverse) {
|
2030 |
+
return array.sort((a, b) => {
|
2031 |
+
const v0 = reverse ? b : a;
|
2032 |
+
const v1 = reverse ? a : b;
|
2033 |
+
return v0.weight === v1.weight ?
|
2034 |
+
v0.index - v1.index :
|
2035 |
+
v0.weight - v1.weight;
|
2036 |
+
});
|
2037 |
+
}
|
2038 |
+
function wrapBoxes(boxes) {
|
2039 |
+
const layoutBoxes = [];
|
2040 |
+
let i, ilen, box, pos, stack, stackWeight;
|
2041 |
+
for (i = 0, ilen = (boxes || []).length; i < ilen; ++i) {
|
2042 |
+
box = boxes[i];
|
2043 |
+
({position: pos, options: {stack, stackWeight = 1}} = box);
|
2044 |
+
layoutBoxes.push({
|
2045 |
+
index: i,
|
2046 |
+
box,
|
2047 |
+
pos,
|
2048 |
+
horizontal: box.isHorizontal(),
|
2049 |
+
weight: box.weight,
|
2050 |
+
stack: stack && (pos + stack),
|
2051 |
+
stackWeight
|
2052 |
+
});
|
2053 |
+
}
|
2054 |
+
return layoutBoxes;
|
2055 |
+
}
|
2056 |
+
function buildStacks(layouts) {
|
2057 |
+
const stacks = {};
|
2058 |
+
for (const wrap of layouts) {
|
2059 |
+
const {stack, pos, stackWeight} = wrap;
|
2060 |
+
if (!stack || !STATIC_POSITIONS.includes(pos)) {
|
2061 |
+
continue;
|
2062 |
+
}
|
2063 |
+
const _stack = stacks[stack] || (stacks[stack] = {count: 0, placed: 0, weight: 0, size: 0});
|
2064 |
+
_stack.count++;
|
2065 |
+
_stack.weight += stackWeight;
|
2066 |
+
}
|
2067 |
+
return stacks;
|
2068 |
+
}
|
2069 |
+
function setLayoutDims(layouts, params) {
|
2070 |
+
const stacks = buildStacks(layouts);
|
2071 |
+
const {vBoxMaxWidth, hBoxMaxHeight} = params;
|
2072 |
+
let i, ilen, layout;
|
2073 |
+
for (i = 0, ilen = layouts.length; i < ilen; ++i) {
|
2074 |
+
layout = layouts[i];
|
2075 |
+
const {fullSize} = layout.box;
|
2076 |
+
const stack = stacks[layout.stack];
|
2077 |
+
const factor = stack && layout.stackWeight / stack.weight;
|
2078 |
+
if (layout.horizontal) {
|
2079 |
+
layout.width = factor ? factor * vBoxMaxWidth : fullSize && params.availableWidth;
|
2080 |
+
layout.height = hBoxMaxHeight;
|
2081 |
+
} else {
|
2082 |
+
layout.width = vBoxMaxWidth;
|
2083 |
+
layout.height = factor ? factor * hBoxMaxHeight : fullSize && params.availableHeight;
|
2084 |
+
}
|
2085 |
+
}
|
2086 |
+
return stacks;
|
2087 |
+
}
|
2088 |
+
function buildLayoutBoxes(boxes) {
|
2089 |
+
const layoutBoxes = wrapBoxes(boxes);
|
2090 |
+
const fullSize = sortByWeight(layoutBoxes.filter(wrap => wrap.box.fullSize), true);
|
2091 |
+
const left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);
|
2092 |
+
const right = sortByWeight(filterByPosition(layoutBoxes, 'right'));
|
2093 |
+
const top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);
|
2094 |
+
const bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));
|
2095 |
+
const centerHorizontal = filterDynamicPositionByAxis(layoutBoxes, 'x');
|
2096 |
+
const centerVertical = filterDynamicPositionByAxis(layoutBoxes, 'y');
|
2097 |
+
return {
|
2098 |
+
fullSize,
|
2099 |
+
leftAndTop: left.concat(top),
|
2100 |
+
rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal),
|
2101 |
+
chartArea: filterByPosition(layoutBoxes, 'chartArea'),
|
2102 |
+
vertical: left.concat(right).concat(centerVertical),
|
2103 |
+
horizontal: top.concat(bottom).concat(centerHorizontal)
|
2104 |
+
};
|
2105 |
+
}
|
2106 |
+
function getCombinedMax(maxPadding, chartArea, a, b) {
|
2107 |
+
return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]);
|
2108 |
+
}
|
2109 |
+
function updateMaxPadding(maxPadding, boxPadding) {
|
2110 |
+
maxPadding.top = Math.max(maxPadding.top, boxPadding.top);
|
2111 |
+
maxPadding.left = Math.max(maxPadding.left, boxPadding.left);
|
2112 |
+
maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);
|
2113 |
+
maxPadding.right = Math.max(maxPadding.right, boxPadding.right);
|
2114 |
+
}
|
2115 |
+
function updateDims(chartArea, params, layout, stacks) {
|
2116 |
+
const {pos, box} = layout;
|
2117 |
+
const maxPadding = chartArea.maxPadding;
|
2118 |
+
if (!isObject(pos)) {
|
2119 |
+
if (layout.size) {
|
2120 |
+
chartArea[pos] -= layout.size;
|
2121 |
+
}
|
2122 |
+
const stack = stacks[layout.stack] || {size: 0, count: 1};
|
2123 |
+
stack.size = Math.max(stack.size, layout.horizontal ? box.height : box.width);
|
2124 |
+
layout.size = stack.size / stack.count;
|
2125 |
+
chartArea[pos] += layout.size;
|
2126 |
+
}
|
2127 |
+
if (box.getPadding) {
|
2128 |
+
updateMaxPadding(maxPadding, box.getPadding());
|
2129 |
+
}
|
2130 |
+
const newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'));
|
2131 |
+
const newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'));
|
2132 |
+
const widthChanged = newWidth !== chartArea.w;
|
2133 |
+
const heightChanged = newHeight !== chartArea.h;
|
2134 |
+
chartArea.w = newWidth;
|
2135 |
+
chartArea.h = newHeight;
|
2136 |
+
return layout.horizontal
|
2137 |
+
? {same: widthChanged, other: heightChanged}
|
2138 |
+
: {same: heightChanged, other: widthChanged};
|
2139 |
+
}
|
2140 |
+
function handleMaxPadding(chartArea) {
|
2141 |
+
const maxPadding = chartArea.maxPadding;
|
2142 |
+
function updatePos(pos) {
|
2143 |
+
const change = Math.max(maxPadding[pos] - chartArea[pos], 0);
|
2144 |
+
chartArea[pos] += change;
|
2145 |
+
return change;
|
2146 |
+
}
|
2147 |
+
chartArea.y += updatePos('top');
|
2148 |
+
chartArea.x += updatePos('left');
|
2149 |
+
updatePos('right');
|
2150 |
+
updatePos('bottom');
|
2151 |
+
}
|
2152 |
+
function getMargins(horizontal, chartArea) {
|
2153 |
+
const maxPadding = chartArea.maxPadding;
|
2154 |
+
function marginForPositions(positions) {
|
2155 |
+
const margin = {left: 0, top: 0, right: 0, bottom: 0};
|
2156 |
+
positions.forEach((pos) => {
|
2157 |
+
margin[pos] = Math.max(chartArea[pos], maxPadding[pos]);
|
2158 |
+
});
|
2159 |
+
return margin;
|
2160 |
+
}
|
2161 |
+
return horizontal
|
2162 |
+
? marginForPositions(['left', 'right'])
|
2163 |
+
: marginForPositions(['top', 'bottom']);
|
2164 |
+
}
|
2165 |
+
function fitBoxes(boxes, chartArea, params, stacks) {
|
2166 |
+
const refitBoxes = [];
|
2167 |
+
let i, ilen, layout, box, refit, changed;
|
2168 |
+
for (i = 0, ilen = boxes.length, refit = 0; i < ilen; ++i) {
|
2169 |
+
layout = boxes[i];
|
2170 |
+
box = layout.box;
|
2171 |
+
box.update(
|
2172 |
+
layout.width || chartArea.w,
|
2173 |
+
layout.height || chartArea.h,
|
2174 |
+
getMargins(layout.horizontal, chartArea)
|
2175 |
+
);
|
2176 |
+
const {same, other} = updateDims(chartArea, params, layout, stacks);
|
2177 |
+
refit |= same && refitBoxes.length;
|
2178 |
+
changed = changed || other;
|
2179 |
+
if (!box.fullSize) {
|
2180 |
+
refitBoxes.push(layout);
|
2181 |
+
}
|
2182 |
+
}
|
2183 |
+
return refit && fitBoxes(refitBoxes, chartArea, params, stacks) || changed;
|
2184 |
+
}
|
2185 |
+
function setBoxDims(box, left, top, width, height) {
|
2186 |
+
box.top = top;
|
2187 |
+
box.left = left;
|
2188 |
+
box.right = left + width;
|
2189 |
+
box.bottom = top + height;
|
2190 |
+
box.width = width;
|
2191 |
+
box.height = height;
|
2192 |
+
}
|
2193 |
+
function placeBoxes(boxes, chartArea, params, stacks) {
|
2194 |
+
const userPadding = params.padding;
|
2195 |
+
let {x, y} = chartArea;
|
2196 |
+
for (const layout of boxes) {
|
2197 |
+
const box = layout.box;
|
2198 |
+
const stack = stacks[layout.stack] || {count: 1, placed: 0, weight: 1};
|
2199 |
+
const weight = (layout.stackWeight / stack.weight) || 1;
|
2200 |
+
if (layout.horizontal) {
|
2201 |
+
const width = chartArea.w * weight;
|
2202 |
+
const height = stack.size || box.height;
|
2203 |
+
if (defined(stack.start)) {
|
2204 |
+
y = stack.start;
|
2205 |
+
}
|
2206 |
+
if (box.fullSize) {
|
2207 |
+
setBoxDims(box, userPadding.left, y, params.outerWidth - userPadding.right - userPadding.left, height);
|
2208 |
+
} else {
|
2209 |
+
setBoxDims(box, chartArea.left + stack.placed, y, width, height);
|
2210 |
+
}
|
2211 |
+
stack.start = y;
|
2212 |
+
stack.placed += width;
|
2213 |
+
y = box.bottom;
|
2214 |
+
} else {
|
2215 |
+
const height = chartArea.h * weight;
|
2216 |
+
const width = stack.size || box.width;
|
2217 |
+
if (defined(stack.start)) {
|
2218 |
+
x = stack.start;
|
2219 |
+
}
|
2220 |
+
if (box.fullSize) {
|
2221 |
+
setBoxDims(box, x, userPadding.top, width, params.outerHeight - userPadding.bottom - userPadding.top);
|
2222 |
+
} else {
|
2223 |
+
setBoxDims(box, x, chartArea.top + stack.placed, width, height);
|
2224 |
+
}
|
2225 |
+
stack.start = x;
|
2226 |
+
stack.placed += height;
|
2227 |
+
x = box.right;
|
2228 |
+
}
|
2229 |
+
}
|
2230 |
+
chartArea.x = x;
|
2231 |
+
chartArea.y = y;
|
2232 |
+
}
|
2233 |
+
defaults.set('layout', {
|
2234 |
+
autoPadding: true,
|
2235 |
+
padding: {
|
2236 |
+
top: 0,
|
2237 |
+
right: 0,
|
2238 |
+
bottom: 0,
|
2239 |
+
left: 0
|
2240 |
+
}
|
2241 |
+
});
|
2242 |
+
var layouts = {
|
2243 |
+
addBox(chart, item) {
|
2244 |
+
if (!chart.boxes) {
|
2245 |
+
chart.boxes = [];
|
2246 |
+
}
|
2247 |
+
item.fullSize = item.fullSize || false;
|
2248 |
+
item.position = item.position || 'top';
|
2249 |
+
item.weight = item.weight || 0;
|
2250 |
+
item._layers = item._layers || function() {
|
2251 |
+
return [{
|
2252 |
+
z: 0,
|
2253 |
+
draw(chartArea) {
|
2254 |
+
item.draw(chartArea);
|
2255 |
}
|
2256 |
+
}];
|
2257 |
+
};
|
2258 |
+
chart.boxes.push(item);
|
2259 |
+
},
|
2260 |
+
removeBox(chart, layoutItem) {
|
2261 |
+
const index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;
|
2262 |
+
if (index !== -1) {
|
2263 |
+
chart.boxes.splice(index, 1);
|
2264 |
+
}
|
2265 |
+
},
|
2266 |
+
configure(chart, item, options) {
|
2267 |
+
item.fullSize = options.fullSize;
|
2268 |
+
item.position = options.position;
|
2269 |
+
item.weight = options.weight;
|
2270 |
+
},
|
2271 |
+
update(chart, width, height, minPadding) {
|
2272 |
+
if (!chart) {
|
2273 |
+
return;
|
2274 |
+
}
|
2275 |
+
const padding = toPadding(chart.options.layout.padding);
|
2276 |
+
const availableWidth = Math.max(width - padding.width, 0);
|
2277 |
+
const availableHeight = Math.max(height - padding.height, 0);
|
2278 |
+
const boxes = buildLayoutBoxes(chart.boxes);
|
2279 |
+
const verticalBoxes = boxes.vertical;
|
2280 |
+
const horizontalBoxes = boxes.horizontal;
|
2281 |
+
each(chart.boxes, box => {
|
2282 |
+
if (typeof box.beforeLayout === 'function') {
|
2283 |
+
box.beforeLayout();
|
2284 |
+
}
|
2285 |
+
});
|
2286 |
+
const visibleVerticalBoxCount = verticalBoxes.reduce((total, wrap) =>
|
2287 |
+
wrap.box.options && wrap.box.options.display === false ? total : total + 1, 0) || 1;
|
2288 |
+
const params = Object.freeze({
|
2289 |
+
outerWidth: width,
|
2290 |
+
outerHeight: height,
|
2291 |
+
padding,
|
2292 |
+
availableWidth,
|
2293 |
+
availableHeight,
|
2294 |
+
vBoxMaxWidth: availableWidth / 2 / visibleVerticalBoxCount,
|
2295 |
+
hBoxMaxHeight: availableHeight / 2
|
2296 |
+
});
|
2297 |
+
const maxPadding = Object.assign({}, padding);
|
2298 |
+
updateMaxPadding(maxPadding, toPadding(minPadding));
|
2299 |
+
const chartArea = Object.assign({
|
2300 |
+
maxPadding,
|
2301 |
+
w: availableWidth,
|
2302 |
+
h: availableHeight,
|
2303 |
+
x: padding.left,
|
2304 |
+
y: padding.top
|
2305 |
+
}, padding);
|
2306 |
+
const stacks = setLayoutDims(verticalBoxes.concat(horizontalBoxes), params);
|
2307 |
+
fitBoxes(boxes.fullSize, chartArea, params, stacks);
|
2308 |
+
fitBoxes(verticalBoxes, chartArea, params, stacks);
|
2309 |
+
if (fitBoxes(horizontalBoxes, chartArea, params, stacks)) {
|
2310 |
+
fitBoxes(verticalBoxes, chartArea, params, stacks);
|
2311 |
+
}
|
2312 |
+
handleMaxPadding(chartArea);
|
2313 |
+
placeBoxes(boxes.leftAndTop, chartArea, params, stacks);
|
2314 |
+
chartArea.x += chartArea.w;
|
2315 |
+
chartArea.y += chartArea.h;
|
2316 |
+
placeBoxes(boxes.rightAndBottom, chartArea, params, stacks);
|
2317 |
+
chart.chartArea = {
|
2318 |
+
left: chartArea.left,
|
2319 |
+
top: chartArea.top,
|
2320 |
+
right: chartArea.left + chartArea.w,
|
2321 |
+
bottom: chartArea.top + chartArea.h,
|
2322 |
+
height: chartArea.h,
|
2323 |
+
width: chartArea.w,
|
2324 |
+
};
|
2325 |
+
each(boxes.chartArea, (layout) => {
|
2326 |
+
const box = layout.box;
|
2327 |
+
Object.assign(box, chart.chartArea);
|
2328 |
+
box.update(chartArea.w, chartArea.h, {left: 0, top: 0, right: 0, bottom: 0});
|
2329 |
+
});
|
2330 |
+
}
|
2331 |
+
};
|
2332 |
+
|
2333 |
+
function _createResolver(scopes, prefixes = [''], rootScopes = scopes, fallback, getTarget = () => scopes[0]) {
|
2334 |
+
if (!defined(fallback)) {
|
2335 |
+
fallback = _resolve('_fallback', scopes);
|
2336 |
+
}
|
2337 |
+
const cache = {
|
2338 |
+
[Symbol.toStringTag]: 'Object',
|
2339 |
+
_cacheable: true,
|
2340 |
+
_scopes: scopes,
|
2341 |
+
_rootScopes: rootScopes,
|
2342 |
+
_fallback: fallback,
|
2343 |
+
_getTarget: getTarget,
|
2344 |
+
override: (scope) => _createResolver([scope, ...scopes], prefixes, rootScopes, fallback),
|
2345 |
+
};
|
2346 |
+
return new Proxy(cache, {
|
2347 |
+
deleteProperty(target, prop) {
|
2348 |
+
delete target[prop];
|
2349 |
+
delete target._keys;
|
2350 |
+
delete scopes[0][prop];
|
2351 |
+
return true;
|
2352 |
},
|
2353 |
+
get(target, prop) {
|
2354 |
+
return _cached(target, prop,
|
2355 |
+
() => _resolveWithPrefixes(prop, prefixes, scopes, target));
|
|
|
|
|
|
|
|
|
2356 |
},
|
2357 |
+
getOwnPropertyDescriptor(target, prop) {
|
2358 |
+
return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop);
|
2359 |
},
|
2360 |
+
getPrototypeOf() {
|
2361 |
+
return Reflect.getPrototypeOf(scopes[0]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2362 |
},
|
2363 |
+
has(target, prop) {
|
2364 |
+
return getKeysFromAllScopes(target).includes(prop);
|
2365 |
},
|
2366 |
+
ownKeys(target) {
|
2367 |
+
return getKeysFromAllScopes(target);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2368 |
},
|
2369 |
+
set(target, prop, value) {
|
2370 |
+
const storage = target._storage || (target._storage = getTarget());
|
2371 |
+
target[prop] = storage[prop] = value;
|
2372 |
+
delete target._keys;
|
2373 |
+
return true;
|
2374 |
+
}
|
2375 |
+
});
|
2376 |
+
}
|
2377 |
+
function _attachContext(proxy, context, subProxy, descriptorDefaults) {
|
2378 |
+
const cache = {
|
2379 |
+
_cacheable: false,
|
2380 |
+
_proxy: proxy,
|
2381 |
+
_context: context,
|
2382 |
+
_subProxy: subProxy,
|
2383 |
+
_stack: new Set(),
|
2384 |
+
_descriptors: _descriptors(proxy, descriptorDefaults),
|
2385 |
+
setContext: (ctx) => _attachContext(proxy, ctx, subProxy, descriptorDefaults),
|
2386 |
+
override: (scope) => _attachContext(proxy.override(scope), context, subProxy, descriptorDefaults)
|
2387 |
+
};
|
2388 |
+
return new Proxy(cache, {
|
2389 |
+
deleteProperty(target, prop) {
|
2390 |
+
delete target[prop];
|
2391 |
+
delete proxy[prop];
|
2392 |
+
return true;
|
2393 |
},
|
2394 |
+
get(target, prop, receiver) {
|
2395 |
+
return _cached(target, prop,
|
2396 |
+
() => _resolveWithContext(target, prop, receiver));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2397 |
},
|
2398 |
+
getOwnPropertyDescriptor(target, prop) {
|
2399 |
+
return target._descriptors.allKeys
|
2400 |
+
? Reflect.has(proxy, prop) ? {enumerable: true, configurable: true} : undefined
|
2401 |
+
: Reflect.getOwnPropertyDescriptor(proxy, prop);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2402 |
},
|
2403 |
+
getPrototypeOf() {
|
2404 |
+
return Reflect.getPrototypeOf(proxy);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2405 |
},
|
2406 |
+
has(target, prop) {
|
2407 |
+
return Reflect.has(proxy, prop);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2408 |
},
|
2409 |
+
ownKeys() {
|
2410 |
+
return Reflect.ownKeys(proxy);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2411 |
},
|
2412 |
+
set(target, prop, value) {
|
2413 |
+
proxy[prop] = value;
|
2414 |
+
delete target[prop];
|
2415 |
+
return true;
|
2416 |
+
}
|
2417 |
+
});
|
2418 |
+
}
|
2419 |
+
function _descriptors(proxy, defaults = {scriptable: true, indexable: true}) {
|
2420 |
+
const {_scriptable = defaults.scriptable, _indexable = defaults.indexable, _allKeys = defaults.allKeys} = proxy;
|
2421 |
+
return {
|
2422 |
+
allKeys: _allKeys,
|
2423 |
+
scriptable: _scriptable,
|
2424 |
+
indexable: _indexable,
|
2425 |
+
isScriptable: isFunction(_scriptable) ? _scriptable : () => _scriptable,
|
2426 |
+
isIndexable: isFunction(_indexable) ? _indexable : () => _indexable
|
2427 |
+
};
|
2428 |
+
}
|
2429 |
+
const readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name;
|
2430 |
+
const needsSubResolver = (prop, value) => isObject(value) && prop !== 'adapters' &&
|
2431 |
+
(Object.getPrototypeOf(value) === null || value.constructor === Object);
|
2432 |
+
function _cached(target, prop, resolve) {
|
2433 |
+
if (Object.prototype.hasOwnProperty.call(target, prop)) {
|
2434 |
+
return target[prop];
|
2435 |
+
}
|
2436 |
+
const value = resolve();
|
2437 |
+
target[prop] = value;
|
2438 |
+
return value;
|
2439 |
+
}
|
2440 |
+
function _resolveWithContext(target, prop, receiver) {
|
2441 |
+
const {_proxy, _context, _subProxy, _descriptors: descriptors} = target;
|
2442 |
+
let value = _proxy[prop];
|
2443 |
+
if (isFunction(value) && descriptors.isScriptable(prop)) {
|
2444 |
+
value = _resolveScriptable(prop, value, target, receiver);
|
2445 |
+
}
|
2446 |
+
if (isArray(value) && value.length) {
|
2447 |
+
value = _resolveArray(prop, value, target, descriptors.isIndexable);
|
2448 |
+
}
|
2449 |
+
if (needsSubResolver(prop, value)) {
|
2450 |
+
value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors);
|
2451 |
+
}
|
2452 |
+
return value;
|
2453 |
+
}
|
2454 |
+
function _resolveScriptable(prop, value, target, receiver) {
|
2455 |
+
const {_proxy, _context, _subProxy, _stack} = target;
|
2456 |
+
if (_stack.has(prop)) {
|
2457 |
+
throw new Error('Recursion detected: ' + Array.from(_stack).join('->') + '->' + prop);
|
2458 |
+
}
|
2459 |
+
_stack.add(prop);
|
2460 |
+
value = value(_context, _subProxy || receiver);
|
2461 |
+
_stack.delete(prop);
|
2462 |
+
if (needsSubResolver(prop, value)) {
|
2463 |
+
value = createSubResolver(_proxy._scopes, _proxy, prop, value);
|
2464 |
+
}
|
2465 |
+
return value;
|
2466 |
+
}
|
2467 |
+
function _resolveArray(prop, value, target, isIndexable) {
|
2468 |
+
const {_proxy, _context, _subProxy, _descriptors: descriptors} = target;
|
2469 |
+
if (defined(_context.index) && isIndexable(prop)) {
|
2470 |
+
value = value[_context.index % value.length];
|
2471 |
+
} else if (isObject(value[0])) {
|
2472 |
+
const arr = value;
|
2473 |
+
const scopes = _proxy._scopes.filter(s => s !== arr);
|
2474 |
+
value = [];
|
2475 |
+
for (const item of arr) {
|
2476 |
+
const resolver = createSubResolver(scopes, _proxy, prop, item);
|
2477 |
+
value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors));
|
2478 |
+
}
|
2479 |
+
}
|
2480 |
+
return value;
|
2481 |
+
}
|
2482 |
+
function resolveFallback(fallback, prop, value) {
|
2483 |
+
return isFunction(fallback) ? fallback(prop, value) : fallback;
|
2484 |
+
}
|
2485 |
+
const getScope = (key, parent) => key === true ? parent
|
2486 |
+
: typeof key === 'string' ? resolveObjectKey(parent, key) : undefined;
|
2487 |
+
function addScopes(set, parentScopes, key, parentFallback, value) {
|
2488 |
+
for (const parent of parentScopes) {
|
2489 |
+
const scope = getScope(key, parent);
|
2490 |
+
if (scope) {
|
2491 |
+
set.add(scope);
|
2492 |
+
const fallback = resolveFallback(scope._fallback, key, value);
|
2493 |
+
if (defined(fallback) && fallback !== key && fallback !== parentFallback) {
|
2494 |
+
return fallback;
|
2495 |
+
}
|
2496 |
+
} else if (scope === false && defined(parentFallback) && key !== parentFallback) {
|
2497 |
+
return null;
|
2498 |
+
}
|
2499 |
+
}
|
2500 |
+
return false;
|
2501 |
+
}
|
2502 |
+
function createSubResolver(parentScopes, resolver, prop, value) {
|
2503 |
+
const rootScopes = resolver._rootScopes;
|
2504 |
+
const fallback = resolveFallback(resolver._fallback, prop, value);
|
2505 |
+
const allScopes = [...parentScopes, ...rootScopes];
|
2506 |
+
const set = new Set();
|
2507 |
+
set.add(value);
|
2508 |
+
let key = addScopesFromKey(set, allScopes, prop, fallback || prop, value);
|
2509 |
+
if (key === null) {
|
2510 |
+
return false;
|
2511 |
+
}
|
2512 |
+
if (defined(fallback) && fallback !== prop) {
|
2513 |
+
key = addScopesFromKey(set, allScopes, fallback, key, value);
|
2514 |
+
if (key === null) {
|
2515 |
+
return false;
|
2516 |
+
}
|
2517 |
+
}
|
2518 |
+
return _createResolver(Array.from(set), [''], rootScopes, fallback,
|
2519 |
+
() => subGetTarget(resolver, prop, value));
|
2520 |
+
}
|
2521 |
+
function addScopesFromKey(set, allScopes, key, fallback, item) {
|
2522 |
+
while (key) {
|
2523 |
+
key = addScopes(set, allScopes, key, fallback, item);
|
2524 |
+
}
|
2525 |
+
return key;
|
2526 |
+
}
|
2527 |
+
function subGetTarget(resolver, prop, value) {
|
2528 |
+
const parent = resolver._getTarget();
|
2529 |
+
if (!(prop in parent)) {
|
2530 |
+
parent[prop] = {};
|
2531 |
+
}
|
2532 |
+
const target = parent[prop];
|
2533 |
+
if (isArray(target) && isObject(value)) {
|
2534 |
+
return value;
|
2535 |
+
}
|
2536 |
+
return target;
|
2537 |
+
}
|
2538 |
+
function _resolveWithPrefixes(prop, prefixes, scopes, proxy) {
|
2539 |
+
let value;
|
2540 |
+
for (const prefix of prefixes) {
|
2541 |
+
value = _resolve(readKey(prefix, prop), scopes);
|
2542 |
+
if (defined(value)) {
|
2543 |
+
return needsSubResolver(prop, value)
|
2544 |
+
? createSubResolver(scopes, proxy, prop, value)
|
2545 |
+
: value;
|
2546 |
+
}
|
2547 |
+
}
|
2548 |
+
}
|
2549 |
+
function _resolve(key, scopes) {
|
2550 |
+
for (const scope of scopes) {
|
2551 |
+
if (!scope) {
|
2552 |
+
continue;
|
2553 |
+
}
|
2554 |
+
const value = scope[key];
|
2555 |
+
if (defined(value)) {
|
2556 |
+
return value;
|
2557 |
+
}
|
2558 |
+
}
|
2559 |
+
}
|
2560 |
+
function getKeysFromAllScopes(target) {
|
2561 |
+
let keys = target._keys;
|
2562 |
+
if (!keys) {
|
2563 |
+
keys = target._keys = resolveKeysFromAllScopes(target._scopes);
|
2564 |
+
}
|
2565 |
+
return keys;
|
2566 |
+
}
|
2567 |
+
function resolveKeysFromAllScopes(scopes) {
|
2568 |
+
const set = new Set();
|
2569 |
+
for (const scope of scopes) {
|
2570 |
+
for (const key of Object.keys(scope).filter(k => !k.startsWith('_'))) {
|
2571 |
+
set.add(key);
|
2572 |
+
}
|
2573 |
+
}
|
2574 |
+
return Array.from(set);
|
2575 |
+
}
|
2576 |
+
|
2577 |
+
const EPSILON = Number.EPSILON || 1e-14;
|
2578 |
+
const getPoint = (points, i) => i < points.length && !points[i].skip && points[i];
|
2579 |
+
const getValueAxis = (indexAxis) => indexAxis === 'x' ? 'y' : 'x';
|
2580 |
+
function splineCurve(firstPoint, middlePoint, afterPoint, t) {
|
2581 |
+
const previous = firstPoint.skip ? middlePoint : firstPoint;
|
2582 |
+
const current = middlePoint;
|
2583 |
+
const next = afterPoint.skip ? middlePoint : afterPoint;
|
2584 |
+
const d01 = distanceBetweenPoints(current, previous);
|
2585 |
+
const d12 = distanceBetweenPoints(next, current);
|
2586 |
+
let s01 = d01 / (d01 + d12);
|
2587 |
+
let s12 = d12 / (d01 + d12);
|
2588 |
+
s01 = isNaN(s01) ? 0 : s01;
|
2589 |
+
s12 = isNaN(s12) ? 0 : s12;
|
2590 |
+
const fa = t * s01;
|
2591 |
+
const fb = t * s12;
|
2592 |
+
return {
|
2593 |
+
previous: {
|
2594 |
+
x: current.x - fa * (next.x - previous.x),
|
2595 |
+
y: current.y - fa * (next.y - previous.y)
|
2596 |
},
|
2597 |
+
next: {
|
2598 |
+
x: current.x + fb * (next.x - previous.x),
|
2599 |
+
y: current.y + fb * (next.y - previous.y)
|
2600 |
+
}
|
2601 |
+
};
|
2602 |
+
}
|
2603 |
+
function monotoneAdjust(points, deltaK, mK) {
|
2604 |
+
const pointsLen = points.length;
|
2605 |
+
let alphaK, betaK, tauK, squaredMagnitude, pointCurrent;
|
2606 |
+
let pointAfter = getPoint(points, 0);
|
2607 |
+
for (let i = 0; i < pointsLen - 1; ++i) {
|
2608 |
+
pointCurrent = pointAfter;
|
2609 |
+
pointAfter = getPoint(points, i + 1);
|
2610 |
+
if (!pointCurrent || !pointAfter) {
|
2611 |
+
continue;
|
2612 |
+
}
|
2613 |
+
if (almostEquals(deltaK[i], 0, EPSILON)) {
|
2614 |
+
mK[i] = mK[i + 1] = 0;
|
2615 |
+
continue;
|
2616 |
+
}
|
2617 |
+
alphaK = mK[i] / deltaK[i];
|
2618 |
+
betaK = mK[i + 1] / deltaK[i];
|
2619 |
+
squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
|
2620 |
+
if (squaredMagnitude <= 9) {
|
2621 |
+
continue;
|
2622 |
+
}
|
2623 |
+
tauK = 3 / Math.sqrt(squaredMagnitude);
|
2624 |
+
mK[i] = alphaK * tauK * deltaK[i];
|
2625 |
+
mK[i + 1] = betaK * tauK * deltaK[i];
|
2626 |
+
}
|
2627 |
+
}
|
2628 |
+
function monotoneCompute(points, mK, indexAxis = 'x') {
|
2629 |
+
const valueAxis = getValueAxis(indexAxis);
|
2630 |
+
const pointsLen = points.length;
|
2631 |
+
let delta, pointBefore, pointCurrent;
|
2632 |
+
let pointAfter = getPoint(points, 0);
|
2633 |
+
for (let i = 0; i < pointsLen; ++i) {
|
2634 |
+
pointBefore = pointCurrent;
|
2635 |
+
pointCurrent = pointAfter;
|
2636 |
+
pointAfter = getPoint(points, i + 1);
|
2637 |
+
if (!pointCurrent) {
|
2638 |
+
continue;
|
2639 |
+
}
|
2640 |
+
const iPixel = pointCurrent[indexAxis];
|
2641 |
+
const vPixel = pointCurrent[valueAxis];
|
2642 |
+
if (pointBefore) {
|
2643 |
+
delta = (iPixel - pointBefore[indexAxis]) / 3;
|
2644 |
+
pointCurrent[`cp1${indexAxis}`] = iPixel - delta;
|
2645 |
+
pointCurrent[`cp1${valueAxis}`] = vPixel - delta * mK[i];
|
2646 |
+
}
|
2647 |
+
if (pointAfter) {
|
2648 |
+
delta = (pointAfter[indexAxis] - iPixel) / 3;
|
2649 |
+
pointCurrent[`cp2${indexAxis}`] = iPixel + delta;
|
2650 |
+
pointCurrent[`cp2${valueAxis}`] = vPixel + delta * mK[i];
|
2651 |
+
}
|
2652 |
+
}
|
2653 |
+
}
|
2654 |
+
function splineCurveMonotone(points, indexAxis = 'x') {
|
2655 |
+
const valueAxis = getValueAxis(indexAxis);
|
2656 |
+
const pointsLen = points.length;
|
2657 |
+
const deltaK = Array(pointsLen).fill(0);
|
2658 |
+
const mK = Array(pointsLen);
|
2659 |
+
let i, pointBefore, pointCurrent;
|
2660 |
+
let pointAfter = getPoint(points, 0);
|
2661 |
+
for (i = 0; i < pointsLen; ++i) {
|
2662 |
+
pointBefore = pointCurrent;
|
2663 |
+
pointCurrent = pointAfter;
|
2664 |
+
pointAfter = getPoint(points, i + 1);
|
2665 |
+
if (!pointCurrent) {
|
2666 |
+
continue;
|
2667 |
+
}
|
2668 |
+
if (pointAfter) {
|
2669 |
+
const slopeDelta = pointAfter[indexAxis] - pointCurrent[indexAxis];
|
2670 |
+
deltaK[i] = slopeDelta !== 0 ? (pointAfter[valueAxis] - pointCurrent[valueAxis]) / slopeDelta : 0;
|
2671 |
+
}
|
2672 |
+
mK[i] = !pointBefore ? deltaK[i]
|
2673 |
+
: !pointAfter ? deltaK[i - 1]
|
2674 |
+
: (sign(deltaK[i - 1]) !== sign(deltaK[i])) ? 0
|
2675 |
+
: (deltaK[i - 1] + deltaK[i]) / 2;
|
2676 |
+
}
|
2677 |
+
monotoneAdjust(points, deltaK, mK);
|
2678 |
+
monotoneCompute(points, mK, indexAxis);
|
2679 |
+
}
|
2680 |
+
function capControlPoint(pt, min, max) {
|
2681 |
+
return Math.max(Math.min(pt, max), min);
|
2682 |
+
}
|
2683 |
+
function capBezierPoints(points, area) {
|
2684 |
+
let i, ilen, point, inArea, inAreaPrev;
|
2685 |
+
let inAreaNext = _isPointInArea(points[0], area);
|
2686 |
+
for (i = 0, ilen = points.length; i < ilen; ++i) {
|
2687 |
+
inAreaPrev = inArea;
|
2688 |
+
inArea = inAreaNext;
|
2689 |
+
inAreaNext = i < ilen - 1 && _isPointInArea(points[i + 1], area);
|
2690 |
+
if (!inArea) {
|
2691 |
+
continue;
|
2692 |
+
}
|
2693 |
+
point = points[i];
|
2694 |
+
if (inAreaPrev) {
|
2695 |
+
point.cp1x = capControlPoint(point.cp1x, area.left, area.right);
|
2696 |
+
point.cp1y = capControlPoint(point.cp1y, area.top, area.bottom);
|
2697 |
+
}
|
2698 |
+
if (inAreaNext) {
|
2699 |
+
point.cp2x = capControlPoint(point.cp2x, area.left, area.right);
|
2700 |
+
point.cp2y = capControlPoint(point.cp2y, area.top, area.bottom);
|
2701 |
+
}
|
2702 |
+
}
|
2703 |
+
}
|
2704 |
+
function _updateBezierControlPoints(points, options, area, loop, indexAxis) {
|
2705 |
+
let i, ilen, point, controlPoints;
|
2706 |
+
if (options.spanGaps) {
|
2707 |
+
points = points.filter((pt) => !pt.skip);
|
2708 |
+
}
|
2709 |
+
if (options.cubicInterpolationMode === 'monotone') {
|
2710 |
+
splineCurveMonotone(points, indexAxis);
|
2711 |
+
} else {
|
2712 |
+
let prev = loop ? points[points.length - 1] : points[0];
|
2713 |
+
for (i = 0, ilen = points.length; i < ilen; ++i) {
|
2714 |
+
point = points[i];
|
2715 |
+
controlPoints = splineCurve(
|
2716 |
+
prev,
|
2717 |
+
point,
|
2718 |
+
points[Math.min(i + 1, ilen - (loop ? 0 : 1)) % ilen],
|
2719 |
+
options.tension
|
2720 |
+
);
|
2721 |
+
point.cp1x = controlPoints.previous.x;
|
2722 |
+
point.cp1y = controlPoints.previous.y;
|
2723 |
+
point.cp2x = controlPoints.next.x;
|
2724 |
+
point.cp2y = controlPoints.next.y;
|
2725 |
+
prev = point;
|
2726 |
+
}
|
2727 |
+
}
|
2728 |
+
if (options.capBezierPoints) {
|
2729 |
+
capBezierPoints(points, area);
|
2730 |
+
}
|
2731 |
+
}
|
2732 |
+
|
2733 |
+
const atEdge = (t) => t === 0 || t === 1;
|
2734 |
+
const elasticIn = (t, s, p) => -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p));
|
2735 |
+
const elasticOut = (t, s, p) => Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1;
|
2736 |
+
const effects = {
|
2737 |
+
linear: t => t,
|
2738 |
+
easeInQuad: t => t * t,
|
2739 |
+
easeOutQuad: t => -t * (t - 2),
|
2740 |
+
easeInOutQuad: t => ((t /= 0.5) < 1)
|
2741 |
+
? 0.5 * t * t
|
2742 |
+
: -0.5 * ((--t) * (t - 2) - 1),
|
2743 |
+
easeInCubic: t => t * t * t,
|
2744 |
+
easeOutCubic: t => (t -= 1) * t * t + 1,
|
2745 |
+
easeInOutCubic: t => ((t /= 0.5) < 1)
|
2746 |
+
? 0.5 * t * t * t
|
2747 |
+
: 0.5 * ((t -= 2) * t * t + 2),
|
2748 |
+
easeInQuart: t => t * t * t * t,
|
2749 |
+
easeOutQuart: t => -((t -= 1) * t * t * t - 1),
|
2750 |
+
easeInOutQuart: t => ((t /= 0.5) < 1)
|
2751 |
+
? 0.5 * t * t * t * t
|
2752 |
+
: -0.5 * ((t -= 2) * t * t * t - 2),
|
2753 |
+
easeInQuint: t => t * t * t * t * t,
|
2754 |
+
easeOutQuint: t => (t -= 1) * t * t * t * t + 1,
|
2755 |
+
easeInOutQuint: t => ((t /= 0.5) < 1)
|
2756 |
+
? 0.5 * t * t * t * t * t
|
2757 |
+
: 0.5 * ((t -= 2) * t * t * t * t + 2),
|
2758 |
+
easeInSine: t => -Math.cos(t * HALF_PI) + 1,
|
2759 |
+
easeOutSine: t => Math.sin(t * HALF_PI),
|
2760 |
+
easeInOutSine: t => -0.5 * (Math.cos(PI * t) - 1),
|
2761 |
+
easeInExpo: t => (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)),
|
2762 |
+
easeOutExpo: t => (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1,
|
2763 |
+
easeInOutExpo: t => atEdge(t) ? t : t < 0.5
|
2764 |
+
? 0.5 * Math.pow(2, 10 * (t * 2 - 1))
|
2765 |
+
: 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2),
|
2766 |
+
easeInCirc: t => (t >= 1) ? t : -(Math.sqrt(1 - t * t) - 1),
|
2767 |
+
easeOutCirc: t => Math.sqrt(1 - (t -= 1) * t),
|
2768 |
+
easeInOutCirc: t => ((t /= 0.5) < 1)
|
2769 |
+
? -0.5 * (Math.sqrt(1 - t * t) - 1)
|
2770 |
+
: 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1),
|
2771 |
+
easeInElastic: t => atEdge(t) ? t : elasticIn(t, 0.075, 0.3),
|
2772 |
+
easeOutElastic: t => atEdge(t) ? t : elasticOut(t, 0.075, 0.3),
|
2773 |
+
easeInOutElastic(t) {
|
2774 |
+
const s = 0.1125;
|
2775 |
+
const p = 0.45;
|
2776 |
+
return atEdge(t) ? t :
|
2777 |
+
t < 0.5
|
2778 |
+
? 0.5 * elasticIn(t * 2, s, p)
|
2779 |
+
: 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p);
|
2780 |
+
},
|
2781 |
+
easeInBack(t) {
|
2782 |
+
const s = 1.70158;
|
2783 |
+
return t * t * ((s + 1) * t - s);
|
2784 |
+
},
|
2785 |
+
easeOutBack(t) {
|
2786 |
+
const s = 1.70158;
|
2787 |
+
return (t -= 1) * t * ((s + 1) * t + s) + 1;
|
2788 |
+
},
|
2789 |
+
easeInOutBack(t) {
|
2790 |
+
let s = 1.70158;
|
2791 |
+
if ((t /= 0.5) < 1) {
|
2792 |
+
return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));
|
2793 |
+
}
|
2794 |
+
return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
|
2795 |
+
},
|
2796 |
+
easeInBounce: t => 1 - effects.easeOutBounce(1 - t),
|
2797 |
+
easeOutBounce(t) {
|
2798 |
+
const m = 7.5625;
|
2799 |
+
const d = 2.75;
|
2800 |
+
if (t < (1 / d)) {
|
2801 |
+
return m * t * t;
|
2802 |
+
}
|
2803 |
+
if (t < (2 / d)) {
|
2804 |
+
return m * (t -= (1.5 / d)) * t + 0.75;
|
2805 |
+
}
|
2806 |
+
if (t < (2.5 / d)) {
|
2807 |
+
return m * (t -= (2.25 / d)) * t + 0.9375;
|
2808 |
+
}
|
2809 |
+
return m * (t -= (2.625 / d)) * t + 0.984375;
|
2810 |
+
},
|
2811 |
+
easeInOutBounce: t => (t < 0.5)
|
2812 |
+
? effects.easeInBounce(t * 2) * 0.5
|
2813 |
+
: effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5,
|
2814 |
+
};
|
2815 |
+
|
2816 |
+
function _pointInLine(p1, p2, t, mode) {
|
2817 |
+
return {
|
2818 |
+
x: p1.x + t * (p2.x - p1.x),
|
2819 |
+
y: p1.y + t * (p2.y - p1.y)
|
2820 |
+
};
|
2821 |
+
}
|
2822 |
+
function _steppedInterpolation(p1, p2, t, mode) {
|
2823 |
+
return {
|
2824 |
+
x: p1.x + t * (p2.x - p1.x),
|
2825 |
+
y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y
|
2826 |
+
: mode === 'after' ? t < 1 ? p1.y : p2.y
|
2827 |
+
: t > 0 ? p2.y : p1.y
|
2828 |
+
};
|
2829 |
+
}
|
2830 |
+
function _bezierInterpolation(p1, p2, t, mode) {
|
2831 |
+
const cp1 = {x: p1.cp2x, y: p1.cp2y};
|
2832 |
+
const cp2 = {x: p2.cp1x, y: p2.cp1y};
|
2833 |
+
const a = _pointInLine(p1, cp1, t);
|
2834 |
+
const b = _pointInLine(cp1, cp2, t);
|
2835 |
+
const c = _pointInLine(cp2, p2, t);
|
2836 |
+
const d = _pointInLine(a, b, t);
|
2837 |
+
const e = _pointInLine(b, c, t);
|
2838 |
+
return _pointInLine(d, e, t);
|
2839 |
+
}
|
2840 |
+
|
2841 |
+
const intlCache = new Map();
|
2842 |
+
function getNumberFormat(locale, options) {
|
2843 |
+
options = options || {};
|
2844 |
+
const cacheKey = locale + JSON.stringify(options);
|
2845 |
+
let formatter = intlCache.get(cacheKey);
|
2846 |
+
if (!formatter) {
|
2847 |
+
formatter = new Intl.NumberFormat(locale, options);
|
2848 |
+
intlCache.set(cacheKey, formatter);
|
2849 |
+
}
|
2850 |
+
return formatter;
|
2851 |
+
}
|
2852 |
+
function formatNumber(num, locale, options) {
|
2853 |
+
return getNumberFormat(locale, options).format(num);
|
2854 |
+
}
|
2855 |
+
|
2856 |
+
const getRightToLeftAdapter = function(rectX, width) {
|
2857 |
+
return {
|
2858 |
+
x(x) {
|
2859 |
+
return rectX + rectX + width - x;
|
2860 |
},
|
2861 |
+
setWidth(w) {
|
2862 |
+
width = w;
|
|
|
|
|
|
|
|
|
|
|
|
|
2863 |
},
|
2864 |
+
textAlign(align) {
|
2865 |
+
if (align === 'center') {
|
2866 |
+
return align;
|
2867 |
+
}
|
2868 |
+
return align === 'right' ? 'left' : 'right';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2869 |
},
|
2870 |
+
xPlus(x, value) {
|
2871 |
+
return x - value;
|
|
|
|
|
|
|
|
|
2872 |
},
|
2873 |
+
leftForLtr(x, itemWidth) {
|
2874 |
+
return x - itemWidth;
|
|
|
|
|
2875 |
},
|
2876 |
+
};
|
2877 |
+
};
|
2878 |
+
const getLeftToRightAdapter = function() {
|
2879 |
+
return {
|
2880 |
+
x(x) {
|
2881 |
+
return x;
|
2882 |
},
|
2883 |
+
setWidth(w) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2884 |
},
|
2885 |
+
textAlign(align) {
|
2886 |
+
return align;
|
|
|
2887 |
},
|
2888 |
+
xPlus(x, value) {
|
2889 |
+
return x + value;
|
2890 |
},
|
2891 |
+
leftForLtr(x, _itemWidth) {
|
2892 |
+
return x;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2893 |
},
|
2894 |
+
};
|
2895 |
+
};
|
2896 |
+
function getRtlAdapter(rtl, rectX, width) {
|
2897 |
+
return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter();
|
2898 |
+
}
|
2899 |
+
function overrideTextDirection(ctx, direction) {
|
2900 |
+
let style, original;
|
2901 |
+
if (direction === 'ltr' || direction === 'rtl') {
|
2902 |
+
style = ctx.canvas.style;
|
2903 |
+
original = [
|
2904 |
+
style.getPropertyValue('direction'),
|
2905 |
+
style.getPropertyPriority('direction'),
|
2906 |
+
];
|
2907 |
+
style.setProperty('direction', direction, 'important');
|
2908 |
+
ctx.prevTextDirection = original;
|
2909 |
+
}
|
2910 |
+
}
|
2911 |
+
function restoreTextDirection(ctx, original) {
|
2912 |
+
if (original !== undefined) {
|
2913 |
+
delete ctx.prevTextDirection;
|
2914 |
+
ctx.canvas.style.setProperty('direction', original[0], original[1]);
|
2915 |
+
}
|
2916 |
+
}
|
2917 |
+
|
2918 |
+
function propertyFn(property) {
|
2919 |
+
if (property === 'angle') {
|
2920 |
+
return {
|
2921 |
+
between: _angleBetween,
|
2922 |
+
compare: _angleDiff,
|
2923 |
+
normalize: _normalizeAngle,
|
2924 |
};
|
2925 |
+
}
|
2926 |
+
return {
|
2927 |
+
between: _isBetween,
|
2928 |
+
compare: (a, b) => a - b,
|
2929 |
+
normalize: x => x
|
2930 |
+
};
|
2931 |
+
}
|
2932 |
+
function normalizeSegment({start, end, count, loop, style}) {
|
2933 |
+
return {
|
2934 |
+
start: start % count,
|
2935 |
+
end: end % count,
|
2936 |
+
loop: loop && (end - start + 1) % count === 0,
|
2937 |
+
style
|
2938 |
+
};
|
2939 |
+
}
|
2940 |
+
function getSegment(segment, points, bounds) {
|
2941 |
+
const {property, start: startBound, end: endBound} = bounds;
|
2942 |
+
const {between, normalize} = propertyFn(property);
|
2943 |
+
const count = points.length;
|
2944 |
+
let {start, end, loop} = segment;
|
2945 |
+
let i, ilen;
|
2946 |
+
if (loop) {
|
2947 |
+
start += count;
|
2948 |
+
end += count;
|
2949 |
+
for (i = 0, ilen = count; i < ilen; ++i) {
|
2950 |
+
if (!between(normalize(points[start % count][property]), startBound, endBound)) {
|
2951 |
+
break;
|
2952 |
+
}
|
2953 |
+
start--;
|
2954 |
+
end--;
|
2955 |
+
}
|
2956 |
+
start %= count;
|
2957 |
+
end %= count;
|
2958 |
+
}
|
2959 |
+
if (end < start) {
|
2960 |
+
end += count;
|
2961 |
+
}
|
2962 |
+
return {start, end, loop, style: segment.style};
|
2963 |
+
}
|
2964 |
+
function _boundSegment(segment, points, bounds) {
|
2965 |
+
if (!bounds) {
|
2966 |
+
return [segment];
|
2967 |
+
}
|
2968 |
+
const {property, start: startBound, end: endBound} = bounds;
|
2969 |
+
const count = points.length;
|
2970 |
+
const {compare, between, normalize} = propertyFn(property);
|
2971 |
+
const {start, end, loop, style} = getSegment(segment, points, bounds);
|
2972 |
+
const result = [];
|
2973 |
+
let inside = false;
|
2974 |
+
let subStart = null;
|
2975 |
+
let value, point, prevValue;
|
2976 |
+
const startIsBefore = () => between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0;
|
2977 |
+
const endIsBefore = () => compare(endBound, value) === 0 || between(endBound, prevValue, value);
|
2978 |
+
const shouldStart = () => inside || startIsBefore();
|
2979 |
+
const shouldStop = () => !inside || endIsBefore();
|
2980 |
+
for (let i = start, prev = start; i <= end; ++i) {
|
2981 |
+
point = points[i % count];
|
2982 |
+
if (point.skip) {
|
2983 |
+
continue;
|
2984 |
+
}
|
2985 |
+
value = normalize(point[property]);
|
2986 |
+
if (value === prevValue) {
|
2987 |
+
continue;
|
2988 |
+
}
|
2989 |
+
inside = between(value, startBound, endBound);
|
2990 |
+
if (subStart === null && shouldStart()) {
|
2991 |
+
subStart = compare(value, startBound) === 0 ? i : prev;
|
2992 |
+
}
|
2993 |
+
if (subStart !== null && shouldStop()) {
|
2994 |
+
result.push(normalizeSegment({start: subStart, end: i, loop, count, style}));
|
2995 |
+
subStart = null;
|
2996 |
+
}
|
2997 |
+
prev = i;
|
2998 |
+
prevValue = value;
|
2999 |
+
}
|
3000 |
+
if (subStart !== null) {
|
3001 |
+
result.push(normalizeSegment({start: subStart, end, loop, count, style}));
|
3002 |
+
}
|
3003 |
+
return result;
|
3004 |
+
}
|
3005 |
+
function _boundSegments(line, bounds) {
|
3006 |
+
const result = [];
|
3007 |
+
const segments = line.segments;
|
3008 |
+
for (let i = 0; i < segments.length; i++) {
|
3009 |
+
const sub = _boundSegment(segments[i], line.points, bounds);
|
3010 |
+
if (sub.length) {
|
3011 |
+
result.push(...sub);
|
3012 |
+
}
|
3013 |
+
}
|
3014 |
+
return result;
|
3015 |
+
}
|
3016 |
+
function findStartAndEnd(points, count, loop, spanGaps) {
|
3017 |
+
let start = 0;
|
3018 |
+
let end = count - 1;
|
3019 |
+
if (loop && !spanGaps) {
|
3020 |
+
while (start < count && !points[start].skip) {
|
3021 |
+
start++;
|
3022 |
+
}
|
3023 |
+
}
|
3024 |
+
while (start < count && points[start].skip) {
|
3025 |
+
start++;
|
3026 |
+
}
|
3027 |
+
start %= count;
|
3028 |
+
if (loop) {
|
3029 |
+
end += start;
|
3030 |
+
}
|
3031 |
+
while (end > start && points[end % count].skip) {
|
3032 |
+
end--;
|
3033 |
+
}
|
3034 |
+
end %= count;
|
3035 |
+
return {start, end};
|
3036 |
+
}
|
3037 |
+
function solidSegments(points, start, max, loop) {
|
3038 |
+
const count = points.length;
|
3039 |
+
const result = [];
|
3040 |
+
let last = start;
|
3041 |
+
let prev = points[start];
|
3042 |
+
let end;
|
3043 |
+
for (end = start + 1; end <= max; ++end) {
|
3044 |
+
const cur = points[end % count];
|
3045 |
+
if (cur.skip || cur.stop) {
|
3046 |
+
if (!prev.skip) {
|
3047 |
+
loop = false;
|
3048 |
+
result.push({start: start % count, end: (end - 1) % count, loop});
|
3049 |
+
start = last = cur.stop ? end : null;
|
3050 |
+
}
|
3051 |
+
} else {
|
3052 |
+
last = end;
|
3053 |
+
if (prev.skip) {
|
3054 |
+
start = end;
|
3055 |
+
}
|
3056 |
+
}
|
3057 |
+
prev = cur;
|
3058 |
+
}
|
3059 |
+
if (last !== null) {
|
3060 |
+
result.push({start: start % count, end: last % count, loop});
|
3061 |
+
}
|
3062 |
+
return result;
|
3063 |
+
}
|
3064 |
+
function _computeSegments(line, segmentOptions) {
|
3065 |
+
const points = line.points;
|
3066 |
+
const spanGaps = line.options.spanGaps;
|
3067 |
+
const count = points.length;
|
3068 |
+
if (!count) {
|
3069 |
+
return [];
|
3070 |
+
}
|
3071 |
+
const loop = !!line._loop;
|
3072 |
+
const {start, end} = findStartAndEnd(points, count, loop, spanGaps);
|
3073 |
+
if (spanGaps === true) {
|
3074 |
+
return splitByStyles(line, [{start, end, loop}], points, segmentOptions);
|
3075 |
+
}
|
3076 |
+
const max = end < start ? end + count : end;
|
3077 |
+
const completeLoop = !!line._fullLoop && start === 0 && end === count - 1;
|
3078 |
+
return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions);
|
3079 |
+
}
|
3080 |
+
function splitByStyles(line, segments, points, segmentOptions) {
|
3081 |
+
if (!segmentOptions || !segmentOptions.setContext || !points) {
|
3082 |
+
return segments;
|
3083 |
+
}
|
3084 |
+
return doSplitByStyles(line, segments, points, segmentOptions);
|
3085 |
+
}
|
3086 |
+
function doSplitByStyles(line, segments, points, segmentOptions) {
|
3087 |
+
const chartContext = line._chart.getContext();
|
3088 |
+
const baseStyle = readStyle(line.options);
|
3089 |
+
const {_datasetIndex: datasetIndex, options: {spanGaps}} = line;
|
3090 |
+
const count = points.length;
|
3091 |
+
const result = [];
|
3092 |
+
let prevStyle = baseStyle;
|
3093 |
+
let start = segments[0].start;
|
3094 |
+
let i = start;
|
3095 |
+
function addStyle(s, e, l, st) {
|
3096 |
+
const dir = spanGaps ? -1 : 1;
|
3097 |
+
if (s === e) {
|
3098 |
+
return;
|
3099 |
+
}
|
3100 |
+
s += count;
|
3101 |
+
while (points[s % count].skip) {
|
3102 |
+
s -= dir;
|
3103 |
+
}
|
3104 |
+
while (points[e % count].skip) {
|
3105 |
+
e += dir;
|
3106 |
+
}
|
3107 |
+
if (s % count !== e % count) {
|
3108 |
+
result.push({start: s % count, end: e % count, loop: l, style: st});
|
3109 |
+
prevStyle = st;
|
3110 |
+
start = e % count;
|
3111 |
+
}
|
3112 |
+
}
|
3113 |
+
for (const segment of segments) {
|
3114 |
+
start = spanGaps ? start : segment.start;
|
3115 |
+
let prev = points[start % count];
|
3116 |
+
let style;
|
3117 |
+
for (i = start + 1; i <= segment.end; i++) {
|
3118 |
+
const pt = points[i % count];
|
3119 |
+
style = readStyle(segmentOptions.setContext(createContext(chartContext, {
|
3120 |
+
type: 'segment',
|
3121 |
+
p0: prev,
|
3122 |
+
p1: pt,
|
3123 |
+
p0DataIndex: (i - 1) % count,
|
3124 |
+
p1DataIndex: i % count,
|
3125 |
+
datasetIndex
|
3126 |
+
})));
|
3127 |
+
if (styleChanged(style, prevStyle)) {
|
3128 |
+
addStyle(start, i - 1, segment.loop, prevStyle);
|
3129 |
+
}
|
3130 |
+
prev = pt;
|
3131 |
+
prevStyle = style;
|
3132 |
+
}
|
3133 |
+
if (start < i - 1) {
|
3134 |
+
addStyle(start, i - 1, segment.loop, prevStyle);
|
3135 |
+
}
|
3136 |
+
}
|
3137 |
+
return result;
|
3138 |
+
}
|
3139 |
+
function readStyle(options) {
|
3140 |
+
return {
|
3141 |
+
backgroundColor: options.backgroundColor,
|
3142 |
+
borderCapStyle: options.borderCapStyle,
|
3143 |
+
borderDash: options.borderDash,
|
3144 |
+
borderDashOffset: options.borderDashOffset,
|
3145 |
+
borderJoinStyle: options.borderJoinStyle,
|
3146 |
+
borderWidth: options.borderWidth,
|
3147 |
+
borderColor: options.borderColor
|
3148 |
+
};
|
3149 |
+
}
|
3150 |
+
function styleChanged(style, prevStyle) {
|
3151 |
+
return prevStyle && JSON.stringify(style) !== JSON.stringify(prevStyle);
|
3152 |
+
}
|
3153 |
+
|
3154 |
+
var helpers = /*#__PURE__*/Object.freeze({
|
3155 |
+
__proto__: null,
|
3156 |
+
easingEffects: effects,
|
3157 |
+
color: color,
|
3158 |
+
getHoverColor: getHoverColor,
|
3159 |
+
noop: noop,
|
3160 |
+
uid: uid,
|
3161 |
+
isNullOrUndef: isNullOrUndef,
|
3162 |
+
isArray: isArray,
|
3163 |
+
isObject: isObject,
|
3164 |
+
isFinite: isNumberFinite,
|
3165 |
+
finiteOrDefault: finiteOrDefault,
|
3166 |
+
valueOrDefault: valueOrDefault,
|
3167 |
+
toPercentage: toPercentage,
|
3168 |
+
toDimension: toDimension,
|
3169 |
+
callback: callback,
|
3170 |
+
each: each,
|
3171 |
+
_elementsEqual: _elementsEqual,
|
3172 |
+
clone: clone,
|
3173 |
+
_merger: _merger,
|
3174 |
+
merge: merge,
|
3175 |
+
mergeIf: mergeIf,
|
3176 |
+
_mergerIf: _mergerIf,
|
3177 |
+
_deprecated: _deprecated,
|
3178 |
+
resolveObjectKey: resolveObjectKey,
|
3179 |
+
_capitalize: _capitalize,
|
3180 |
+
defined: defined,
|
3181 |
+
isFunction: isFunction,
|
3182 |
+
setsEqual: setsEqual,
|
3183 |
+
_isClickEvent: _isClickEvent,
|
3184 |
+
toFontString: toFontString,
|
3185 |
+
_measureText: _measureText,
|
3186 |
+
_longestText: _longestText,
|
3187 |
+
_alignPixel: _alignPixel,
|
3188 |
+
clearCanvas: clearCanvas,
|
3189 |
+
drawPoint: drawPoint,
|
3190 |
+
_isPointInArea: _isPointInArea,
|
3191 |
+
clipArea: clipArea,
|
3192 |
+
unclipArea: unclipArea,
|
3193 |
+
_steppedLineTo: _steppedLineTo,
|
3194 |
+
_bezierCurveTo: _bezierCurveTo,
|
3195 |
+
renderText: renderText,
|
3196 |
+
addRoundedRectPath: addRoundedRectPath,
|
3197 |
+
_lookup: _lookup,
|
3198 |
+
_lookupByKey: _lookupByKey,
|
3199 |
+
_rlookupByKey: _rlookupByKey,
|
3200 |
+
_filterBetween: _filterBetween,
|
3201 |
+
listenArrayEvents: listenArrayEvents,
|
3202 |
+
unlistenArrayEvents: unlistenArrayEvents,
|
3203 |
+
_arrayUnique: _arrayUnique,
|
3204 |
+
_createResolver: _createResolver,
|
3205 |
+
_attachContext: _attachContext,
|
3206 |
+
_descriptors: _descriptors,
|
3207 |
+
splineCurve: splineCurve,
|
3208 |
+
splineCurveMonotone: splineCurveMonotone,
|
3209 |
+
_updateBezierControlPoints: _updateBezierControlPoints,
|
3210 |
+
_isDomSupported: _isDomSupported,
|
3211 |
+
_getParentNode: _getParentNode,
|
3212 |
+
getStyle: getStyle,
|
3213 |
+
getRelativePosition: getRelativePosition$1,
|
3214 |
+
getMaximumSize: getMaximumSize,
|
3215 |
+
retinaScale: retinaScale,
|
3216 |
+
supportsEventListenerOptions: supportsEventListenerOptions,
|
3217 |
+
readUsedSize: readUsedSize,
|
3218 |
+
fontString: fontString,
|
3219 |
+
requestAnimFrame: requestAnimFrame,
|
3220 |
+
throttled: throttled,
|
3221 |
+
debounce: debounce,
|
3222 |
+
_toLeftRightCenter: _toLeftRightCenter,
|
3223 |
+
_alignStartEnd: _alignStartEnd,
|
3224 |
+
_textX: _textX,
|
3225 |
+
_pointInLine: _pointInLine,
|
3226 |
+
_steppedInterpolation: _steppedInterpolation,
|
3227 |
+
_bezierInterpolation: _bezierInterpolation,
|
3228 |
+
formatNumber: formatNumber,
|
3229 |
+
toLineHeight: toLineHeight,
|
3230 |
+
_readValueToProps: _readValueToProps,
|
3231 |
+
toTRBL: toTRBL,
|
3232 |
+
toTRBLCorners: toTRBLCorners,
|
3233 |
+
toPadding: toPadding,
|
3234 |
+
toFont: toFont,
|
3235 |
+
resolve: resolve,
|
3236 |
+
_addGrace: _addGrace,
|
3237 |
+
createContext: createContext,
|
3238 |
+
PI: PI,
|
3239 |
+
TAU: TAU,
|
3240 |
+
PITAU: PITAU,
|
3241 |
+
INFINITY: INFINITY,
|
3242 |
+
RAD_PER_DEG: RAD_PER_DEG,
|
3243 |
+
HALF_PI: HALF_PI,
|
3244 |
+
QUARTER_PI: QUARTER_PI,
|
3245 |
+
TWO_THIRDS_PI: TWO_THIRDS_PI,
|
3246 |
+
log10: log10,
|
3247 |
+
sign: sign,
|
3248 |
+
niceNum: niceNum,
|
3249 |
+
_factorize: _factorize,
|
3250 |
+
isNumber: isNumber,
|
3251 |
+
almostEquals: almostEquals,
|
3252 |
+
almostWhole: almostWhole,
|
3253 |
+
_setMinAndMaxByKey: _setMinAndMaxByKey,
|
3254 |
+
toRadians: toRadians,
|
3255 |
+
toDegrees: toDegrees,
|
3256 |
+
_decimalPlaces: _decimalPlaces,
|
3257 |
+
getAngleFromPoint: getAngleFromPoint,
|
3258 |
+
distanceBetweenPoints: distanceBetweenPoints,
|
3259 |
+
_angleDiff: _angleDiff,
|
3260 |
+
_normalizeAngle: _normalizeAngle,
|
3261 |
+
_angleBetween: _angleBetween,
|
3262 |
+
_limitValue: _limitValue,
|
3263 |
+
_int16Range: _int16Range,
|
3264 |
+
_isBetween: _isBetween,
|
3265 |
+
getRtlAdapter: getRtlAdapter,
|
3266 |
+
overrideTextDirection: overrideTextDirection,
|
3267 |
+
restoreTextDirection: restoreTextDirection,
|
3268 |
+
_boundSegment: _boundSegment,
|
3269 |
+
_boundSegments: _boundSegments,
|
3270 |
+
_computeSegments: _computeSegments
|
3271 |
+
});
|
3272 |
+
|
3273 |
+
class BasePlatform {
|
3274 |
+
acquireContext(canvas, aspectRatio) {}
|
3275 |
+
releaseContext(context) {
|
3276 |
+
return false;
|
3277 |
+
}
|
3278 |
+
addEventListener(chart, type, listener) {}
|
3279 |
+
removeEventListener(chart, type, listener) {}
|
3280 |
+
getDevicePixelRatio() {
|
3281 |
+
return 1;
|
3282 |
+
}
|
3283 |
+
getMaximumSize(element, width, height, aspectRatio) {
|
3284 |
+
width = Math.max(0, width || element.width);
|
3285 |
+
height = height || element.height;
|
3286 |
+
return {
|
3287 |
+
width,
|
3288 |
+
height: Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height)
|
3289 |
+
};
|
3290 |
+
}
|
3291 |
+
isAttached(canvas) {
|
3292 |
+
return true;
|
3293 |
+
}
|
3294 |
+
updateConfig(config) {
|
3295 |
+
}
|
3296 |
+
}
|
3297 |
+
|
3298 |
+
class BasicPlatform extends BasePlatform {
|
3299 |
+
acquireContext(item) {
|
3300 |
+
return item && item.getContext && item.getContext('2d') || null;
|
3301 |
+
}
|
3302 |
+
updateConfig(config) {
|
3303 |
+
config.options.animation = false;
|
3304 |
+
}
|
3305 |
+
}
|
3306 |
+
|
3307 |
+
const EXPANDO_KEY = '$chartjs';
|
3308 |
+
const EVENT_TYPES = {
|
3309 |
+
touchstart: 'mousedown',
|
3310 |
+
touchmove: 'mousemove',
|
3311 |
+
touchend: 'mouseup',
|
3312 |
+
pointerenter: 'mouseenter',
|
3313 |
+
pointerdown: 'mousedown',
|
3314 |
+
pointermove: 'mousemove',
|
3315 |
+
pointerup: 'mouseup',
|
3316 |
+
pointerleave: 'mouseout',
|
3317 |
+
pointerout: 'mouseout'
|
3318 |
+
};
|
3319 |
+
const isNullOrEmpty = value => value === null || value === '';
|
3320 |
+
function initCanvas(canvas, aspectRatio) {
|
3321 |
+
const style = canvas.style;
|
3322 |
+
const renderHeight = canvas.getAttribute('height');
|
3323 |
+
const renderWidth = canvas.getAttribute('width');
|
3324 |
+
canvas[EXPANDO_KEY] = {
|
3325 |
+
initial: {
|
3326 |
+
height: renderHeight,
|
3327 |
+
width: renderWidth,
|
3328 |
+
style: {
|
3329 |
+
display: style.display,
|
3330 |
+
height: style.height,
|
3331 |
+
width: style.width
|
3332 |
+
}
|
3333 |
+
}
|
3334 |
+
};
|
3335 |
+
style.display = style.display || 'block';
|
3336 |
+
style.boxSizing = style.boxSizing || 'border-box';
|
3337 |
+
if (isNullOrEmpty(renderWidth)) {
|
3338 |
+
const displayWidth = readUsedSize(canvas, 'width');
|
3339 |
+
if (displayWidth !== undefined) {
|
3340 |
+
canvas.width = displayWidth;
|
3341 |
+
}
|
3342 |
+
}
|
3343 |
+
if (isNullOrEmpty(renderHeight)) {
|
3344 |
+
if (canvas.style.height === '') {
|
3345 |
+
canvas.height = canvas.width / (aspectRatio || 2);
|
3346 |
+
} else {
|
3347 |
+
const displayHeight = readUsedSize(canvas, 'height');
|
3348 |
+
if (displayHeight !== undefined) {
|
3349 |
+
canvas.height = displayHeight;
|
3350 |
+
}
|
3351 |
+
}
|
3352 |
+
}
|
3353 |
+
return canvas;
|
3354 |
+
}
|
3355 |
+
const eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;
|
3356 |
+
function addListener(node, type, listener) {
|
3357 |
+
node.addEventListener(type, listener, eventListenerOptions);
|
3358 |
+
}
|
3359 |
+
function removeListener(chart, type, listener) {
|
3360 |
+
chart.canvas.removeEventListener(type, listener, eventListenerOptions);
|
3361 |
+
}
|
3362 |
+
function fromNativeEvent(event, chart) {
|
3363 |
+
const type = EVENT_TYPES[event.type] || event.type;
|
3364 |
+
const {x, y} = getRelativePosition$1(event, chart);
|
3365 |
+
return {
|
3366 |
+
type,
|
3367 |
+
chart,
|
3368 |
+
native: event,
|
3369 |
+
x: x !== undefined ? x : null,
|
3370 |
+
y: y !== undefined ? y : null,
|
3371 |
+
};
|
3372 |
+
}
|
3373 |
+
function nodeListContains(nodeList, canvas) {
|
3374 |
+
for (const node of nodeList) {
|
3375 |
+
if (node === canvas || node.contains(canvas)) {
|
3376 |
+
return true;
|
3377 |
+
}
|
3378 |
+
}
|
3379 |
+
}
|
3380 |
+
function createAttachObserver(chart, type, listener) {
|
3381 |
+
const canvas = chart.canvas;
|
3382 |
+
const observer = new MutationObserver(entries => {
|
3383 |
+
let trigger = false;
|
3384 |
+
for (const entry of entries) {
|
3385 |
+
trigger = trigger || nodeListContains(entry.addedNodes, canvas);
|
3386 |
+
trigger = trigger && !nodeListContains(entry.removedNodes, canvas);
|
3387 |
+
}
|
3388 |
+
if (trigger) {
|
3389 |
+
listener();
|
3390 |
+
}
|
3391 |
+
});
|
3392 |
+
observer.observe(document, {childList: true, subtree: true});
|
3393 |
+
return observer;
|
3394 |
+
}
|
3395 |
+
function createDetachObserver(chart, type, listener) {
|
3396 |
+
const canvas = chart.canvas;
|
3397 |
+
const observer = new MutationObserver(entries => {
|
3398 |
+
let trigger = false;
|
3399 |
+
for (const entry of entries) {
|
3400 |
+
trigger = trigger || nodeListContains(entry.removedNodes, canvas);
|
3401 |
+
trigger = trigger && !nodeListContains(entry.addedNodes, canvas);
|
3402 |
+
}
|
3403 |
+
if (trigger) {
|
3404 |
+
listener();
|
3405 |
+
}
|
3406 |
+
});
|
3407 |
+
observer.observe(document, {childList: true, subtree: true});
|
3408 |
+
return observer;
|
3409 |
+
}
|
3410 |
+
const drpListeningCharts = new Map();
|
3411 |
+
let oldDevicePixelRatio = 0;
|
3412 |
+
function onWindowResize() {
|
3413 |
+
const dpr = window.devicePixelRatio;
|
3414 |
+
if (dpr === oldDevicePixelRatio) {
|
3415 |
+
return;
|
3416 |
+
}
|
3417 |
+
oldDevicePixelRatio = dpr;
|
3418 |
+
drpListeningCharts.forEach((resize, chart) => {
|
3419 |
+
if (chart.currentDevicePixelRatio !== dpr) {
|
3420 |
+
resize();
|
3421 |
+
}
|
3422 |
+
});
|
3423 |
+
}
|
3424 |
+
function listenDevicePixelRatioChanges(chart, resize) {
|
3425 |
+
if (!drpListeningCharts.size) {
|
3426 |
+
window.addEventListener('resize', onWindowResize);
|
3427 |
+
}
|
3428 |
+
drpListeningCharts.set(chart, resize);
|
3429 |
+
}
|
3430 |
+
function unlistenDevicePixelRatioChanges(chart) {
|
3431 |
+
drpListeningCharts.delete(chart);
|
3432 |
+
if (!drpListeningCharts.size) {
|
3433 |
+
window.removeEventListener('resize', onWindowResize);
|
3434 |
+
}
|
3435 |
+
}
|
3436 |
+
function createResizeObserver(chart, type, listener) {
|
3437 |
+
const canvas = chart.canvas;
|
3438 |
+
const container = canvas && _getParentNode(canvas);
|
3439 |
+
if (!container) {
|
3440 |
+
return;
|
3441 |
+
}
|
3442 |
+
const resize = throttled((width, height) => {
|
3443 |
+
const w = container.clientWidth;
|
3444 |
+
listener(width, height);
|
3445 |
+
if (w < container.clientWidth) {
|
3446 |
+
listener();
|
3447 |
+
}
|
3448 |
+
}, window);
|
3449 |
+
const observer = new ResizeObserver(entries => {
|
3450 |
+
const entry = entries[0];
|
3451 |
+
const width = entry.contentRect.width;
|
3452 |
+
const height = entry.contentRect.height;
|
3453 |
+
if (width === 0 && height === 0) {
|
3454 |
+
return;
|
3455 |
+
}
|
3456 |
+
resize(width, height);
|
3457 |
+
});
|
3458 |
+
observer.observe(container);
|
3459 |
+
listenDevicePixelRatioChanges(chart, resize);
|
3460 |
+
return observer;
|
3461 |
+
}
|
3462 |
+
function releaseObserver(chart, type, observer) {
|
3463 |
+
if (observer) {
|
3464 |
+
observer.disconnect();
|
3465 |
+
}
|
3466 |
+
if (type === 'resize') {
|
3467 |
+
unlistenDevicePixelRatioChanges(chart);
|
3468 |
+
}
|
3469 |
+
}
|
3470 |
+
function createProxyAndListen(chart, type, listener) {
|
3471 |
+
const canvas = chart.canvas;
|
3472 |
+
const proxy = throttled((event) => {
|
3473 |
+
if (chart.ctx !== null) {
|
3474 |
+
listener(fromNativeEvent(event, chart));
|
3475 |
+
}
|
3476 |
+
}, chart, (args) => {
|
3477 |
+
const event = args[0];
|
3478 |
+
return [event, event.offsetX, event.offsetY];
|
3479 |
+
});
|
3480 |
+
addListener(canvas, type, proxy);
|
3481 |
+
return proxy;
|
3482 |
+
}
|
3483 |
+
class DomPlatform extends BasePlatform {
|
3484 |
+
acquireContext(canvas, aspectRatio) {
|
3485 |
+
const context = canvas && canvas.getContext && canvas.getContext('2d');
|
3486 |
+
if (context && context.canvas === canvas) {
|
3487 |
+
initCanvas(canvas, aspectRatio);
|
3488 |
+
return context;
|
3489 |
+
}
|
3490 |
+
return null;
|
3491 |
+
}
|
3492 |
+
releaseContext(context) {
|
3493 |
+
const canvas = context.canvas;
|
3494 |
+
if (!canvas[EXPANDO_KEY]) {
|
3495 |
+
return false;
|
3496 |
+
}
|
3497 |
+
const initial = canvas[EXPANDO_KEY].initial;
|
3498 |
+
['height', 'width'].forEach((prop) => {
|
3499 |
+
const value = initial[prop];
|
3500 |
+
if (isNullOrUndef(value)) {
|
3501 |
+
canvas.removeAttribute(prop);
|
3502 |
+
} else {
|
3503 |
+
canvas.setAttribute(prop, value);
|
3504 |
+
}
|
3505 |
+
});
|
3506 |
+
const style = initial.style || {};
|
3507 |
+
Object.keys(style).forEach((key) => {
|
3508 |
+
canvas.style[key] = style[key];
|
3509 |
+
});
|
3510 |
+
canvas.width = canvas.width;
|
3511 |
+
delete canvas[EXPANDO_KEY];
|
3512 |
+
return true;
|
3513 |
+
}
|
3514 |
+
addEventListener(chart, type, listener) {
|
3515 |
+
this.removeEventListener(chart, type);
|
3516 |
+
const proxies = chart.$proxies || (chart.$proxies = {});
|
3517 |
+
const handlers = {
|
3518 |
+
attach: createAttachObserver,
|
3519 |
+
detach: createDetachObserver,
|
3520 |
+
resize: createResizeObserver
|
3521 |
+
};
|
3522 |
+
const handler = handlers[type] || createProxyAndListen;
|
3523 |
+
proxies[type] = handler(chart, type, listener);
|
3524 |
+
}
|
3525 |
+
removeEventListener(chart, type) {
|
3526 |
+
const proxies = chart.$proxies || (chart.$proxies = {});
|
3527 |
+
const proxy = proxies[type];
|
3528 |
+
if (!proxy) {
|
3529 |
+
return;
|
3530 |
+
}
|
3531 |
+
const handlers = {
|
3532 |
+
attach: releaseObserver,
|
3533 |
+
detach: releaseObserver,
|
3534 |
+
resize: releaseObserver
|
3535 |
+
};
|
3536 |
+
const handler = handlers[type] || removeListener;
|
3537 |
+
handler(chart, type, proxy);
|
3538 |
+
proxies[type] = undefined;
|
3539 |
+
}
|
3540 |
+
getDevicePixelRatio() {
|
3541 |
+
return window.devicePixelRatio;
|
3542 |
+
}
|
3543 |
+
getMaximumSize(canvas, width, height, aspectRatio) {
|
3544 |
+
return getMaximumSize(canvas, width, height, aspectRatio);
|
3545 |
+
}
|
3546 |
+
isAttached(canvas) {
|
3547 |
+
const container = _getParentNode(canvas);
|
3548 |
+
return !!(container && container.isConnected);
|
3549 |
+
}
|
3550 |
+
}
|
3551 |
+
|
3552 |
+
function _detectPlatform(canvas) {
|
3553 |
+
if (!_isDomSupported() || (typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas)) {
|
3554 |
+
return BasicPlatform;
|
3555 |
+
}
|
3556 |
+
return DomPlatform;
|
3557 |
+
}
|
3558 |
+
|
3559 |
+
var platforms = /*#__PURE__*/Object.freeze({
|
3560 |
+
__proto__: null,
|
3561 |
+
_detectPlatform: _detectPlatform,
|
3562 |
+
BasePlatform: BasePlatform,
|
3563 |
+
BasicPlatform: BasicPlatform,
|
3564 |
+
DomPlatform: DomPlatform
|
3565 |
+
});
|
3566 |
+
|
3567 |
+
const transparent = 'transparent';
|
3568 |
+
const interpolators = {
|
3569 |
+
boolean(from, to, factor) {
|
3570 |
+
return factor > 0.5 ? to : from;
|
3571 |
+
},
|
3572 |
+
color(from, to, factor) {
|
3573 |
+
const c0 = color(from || transparent);
|
3574 |
+
const c1 = c0.valid && color(to || transparent);
|
3575 |
+
return c1 && c1.valid
|
3576 |
+
? c1.mix(c0, factor).hexString()
|
3577 |
+
: to;
|
3578 |
+
},
|
3579 |
+
number(from, to, factor) {
|
3580 |
+
return from + (to - from) * factor;
|
3581 |
+
}
|
3582 |
+
};
|
3583 |
+
class Animation {
|
3584 |
+
constructor(cfg, target, prop, to) {
|
3585 |
+
const currentValue = target[prop];
|
3586 |
+
to = resolve([cfg.to, to, currentValue, cfg.from]);
|
3587 |
+
const from = resolve([cfg.from, currentValue, to]);
|
3588 |
+
this._active = true;
|
3589 |
+
this._fn = cfg.fn || interpolators[cfg.type || typeof from];
|
3590 |
+
this._easing = effects[cfg.easing] || effects.linear;
|
3591 |
+
this._start = Math.floor(Date.now() + (cfg.delay || 0));
|
3592 |
+
this._duration = this._total = Math.floor(cfg.duration);
|
3593 |
+
this._loop = !!cfg.loop;
|
3594 |
+
this._target = target;
|
3595 |
+
this._prop = prop;
|
3596 |
+
this._from = from;
|
3597 |
+
this._to = to;
|
3598 |
+
this._promises = undefined;
|
3599 |
+
}
|
3600 |
+
active() {
|
3601 |
+
return this._active;
|
3602 |
+
}
|
3603 |
+
update(cfg, to, date) {
|
3604 |
+
if (this._active) {
|
3605 |
+
this._notify(false);
|
3606 |
+
const currentValue = this._target[this._prop];
|
3607 |
+
const elapsed = date - this._start;
|
3608 |
+
const remain = this._duration - elapsed;
|
3609 |
+
this._start = date;
|
3610 |
+
this._duration = Math.floor(Math.max(remain, cfg.duration));
|
3611 |
+
this._total += elapsed;
|
3612 |
+
this._loop = !!cfg.loop;
|
3613 |
+
this._to = resolve([cfg.to, to, currentValue, cfg.from]);
|
3614 |
+
this._from = resolve([cfg.from, currentValue, to]);
|
3615 |
+
}
|
3616 |
+
}
|
3617 |
+
cancel() {
|
3618 |
+
if (this._active) {
|
3619 |
+
this.tick(Date.now());
|
3620 |
+
this._active = false;
|
3621 |
+
this._notify(false);
|
3622 |
+
}
|
3623 |
+
}
|
3624 |
+
tick(date) {
|
3625 |
+
const elapsed = date - this._start;
|
3626 |
+
const duration = this._duration;
|
3627 |
+
const prop = this._prop;
|
3628 |
+
const from = this._from;
|
3629 |
+
const loop = this._loop;
|
3630 |
+
const to = this._to;
|
3631 |
+
let factor;
|
3632 |
+
this._active = from !== to && (loop || (elapsed < duration));
|
3633 |
+
if (!this._active) {
|
3634 |
+
this._target[prop] = to;
|
3635 |
+
this._notify(true);
|
3636 |
+
return;
|
3637 |
+
}
|
3638 |
+
if (elapsed < 0) {
|
3639 |
+
this._target[prop] = from;
|
3640 |
+
return;
|
3641 |
+
}
|
3642 |
+
factor = (elapsed / duration) % 2;
|
3643 |
+
factor = loop && factor > 1 ? 2 - factor : factor;
|
3644 |
+
factor = this._easing(Math.min(1, Math.max(0, factor)));
|
3645 |
+
this._target[prop] = this._fn(from, to, factor);
|
3646 |
+
}
|
3647 |
+
wait() {
|
3648 |
+
const promises = this._promises || (this._promises = []);
|
3649 |
+
return new Promise((res, rej) => {
|
3650 |
+
promises.push({res, rej});
|
3651 |
+
});
|
3652 |
+
}
|
3653 |
+
_notify(resolved) {
|
3654 |
+
const method = resolved ? 'res' : 'rej';
|
3655 |
+
const promises = this._promises || [];
|
3656 |
+
for (let i = 0; i < promises.length; i++) {
|
3657 |
+
promises[i][method]();
|
3658 |
+
}
|
3659 |
+
}
|
3660 |
+
}
|
3661 |
+
|
3662 |
+
const numbers = ['x', 'y', 'borderWidth', 'radius', 'tension'];
|
3663 |
+
const colors = ['color', 'borderColor', 'backgroundColor'];
|
3664 |
+
defaults.set('animation', {
|
3665 |
+
delay: undefined,
|
3666 |
+
duration: 1000,
|
3667 |
+
easing: 'easeOutQuart',
|
3668 |
+
fn: undefined,
|
3669 |
+
from: undefined,
|
3670 |
+
loop: undefined,
|
3671 |
+
to: undefined,
|
3672 |
+
type: undefined,
|
3673 |
+
});
|
3674 |
+
const animationOptions = Object.keys(defaults.animation);
|
3675 |
+
defaults.describe('animation', {
|
3676 |
+
_fallback: false,
|
3677 |
+
_indexable: false,
|
3678 |
+
_scriptable: (name) => name !== 'onProgress' && name !== 'onComplete' && name !== 'fn',
|
3679 |
+
});
|
3680 |
+
defaults.set('animations', {
|
3681 |
+
colors: {
|
3682 |
+
type: 'color',
|
3683 |
+
properties: colors
|
3684 |
+
},
|
3685 |
+
numbers: {
|
3686 |
+
type: 'number',
|
3687 |
+
properties: numbers
|
3688 |
+
},
|
3689 |
+
});
|
3690 |
+
defaults.describe('animations', {
|
3691 |
+
_fallback: 'animation',
|
3692 |
+
});
|
3693 |
+
defaults.set('transitions', {
|
3694 |
+
active: {
|
3695 |
+
animation: {
|
3696 |
+
duration: 400
|
3697 |
+
}
|
3698 |
+
},
|
3699 |
+
resize: {
|
3700 |
+
animation: {
|
3701 |
+
duration: 0
|
3702 |
+
}
|
3703 |
+
},
|
3704 |
+
show: {
|
3705 |
+
animations: {
|
3706 |
+
colors: {
|
3707 |
+
from: 'transparent'
|
3708 |
+
},
|
3709 |
+
visible: {
|
3710 |
+
type: 'boolean',
|
3711 |
+
duration: 0
|
3712 |
+
},
|
3713 |
+
}
|
3714 |
+
},
|
3715 |
+
hide: {
|
3716 |
+
animations: {
|
3717 |
+
colors: {
|
3718 |
+
to: 'transparent'
|
3719 |
+
},
|
3720 |
+
visible: {
|
3721 |
+
type: 'boolean',
|
3722 |
+
easing: 'linear',
|
3723 |
+
fn: v => v | 0
|
3724 |
+
},
|
3725 |
+
}
|
3726 |
+
}
|
3727 |
+
});
|
3728 |
+
class Animations {
|
3729 |
+
constructor(chart, config) {
|
3730 |
+
this._chart = chart;
|
3731 |
+
this._properties = new Map();
|
3732 |
+
this.configure(config);
|
3733 |
+
}
|
3734 |
+
configure(config) {
|
3735 |
+
if (!isObject(config)) {
|
3736 |
+
return;
|
3737 |
+
}
|
3738 |
+
const animatedProps = this._properties;
|
3739 |
+
Object.getOwnPropertyNames(config).forEach(key => {
|
3740 |
+
const cfg = config[key];
|
3741 |
+
if (!isObject(cfg)) {
|
3742 |
+
return;
|
3743 |
+
}
|
3744 |
+
const resolved = {};
|
3745 |
+
for (const option of animationOptions) {
|
3746 |
+
resolved[option] = cfg[option];
|
3747 |
+
}
|
3748 |
+
(isArray(cfg.properties) && cfg.properties || [key]).forEach((prop) => {
|
3749 |
+
if (prop === key || !animatedProps.has(prop)) {
|
3750 |
+
animatedProps.set(prop, resolved);
|
3751 |
}
|
3752 |
+
});
|
3753 |
+
});
|
3754 |
+
}
|
3755 |
+
_animateOptions(target, values) {
|
3756 |
+
const newOptions = values.options;
|
3757 |
+
const options = resolveTargetOptions(target, newOptions);
|
3758 |
+
if (!options) {
|
3759 |
+
return [];
|
3760 |
+
}
|
3761 |
+
const animations = this._createAnimations(options, newOptions);
|
3762 |
+
if (newOptions.$shared) {
|
3763 |
+
awaitAll(target.options.$animations, newOptions).then(() => {
|
3764 |
+
target.options = newOptions;
|
3765 |
+
}, () => {
|
3766 |
+
});
|
3767 |
+
}
|
3768 |
+
return animations;
|
3769 |
+
}
|
3770 |
+
_createAnimations(target, values) {
|
3771 |
+
const animatedProps = this._properties;
|
3772 |
+
const animations = [];
|
3773 |
+
const running = target.$animations || (target.$animations = {});
|
3774 |
+
const props = Object.keys(values);
|
3775 |
+
const date = Date.now();
|
3776 |
+
let i;
|
3777 |
+
for (i = props.length - 1; i >= 0; --i) {
|
3778 |
+
const prop = props[i];
|
3779 |
+
if (prop.charAt(0) === '$') {
|
3780 |
+
continue;
|
3781 |
+
}
|
3782 |
+
if (prop === 'options') {
|
3783 |
+
animations.push(...this._animateOptions(target, values));
|
3784 |
+
continue;
|
3785 |
+
}
|
3786 |
+
const value = values[prop];
|
3787 |
+
let animation = running[prop];
|
3788 |
+
const cfg = animatedProps.get(prop);
|
3789 |
+
if (animation) {
|
3790 |
+
if (cfg && animation.active()) {
|
3791 |
+
animation.update(cfg, value, date);
|
3792 |
+
continue;
|
3793 |
+
} else {
|
3794 |
+
animation.cancel();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3795 |
}
|
3796 |
+
}
|
3797 |
+
if (!cfg || !cfg.duration) {
|
3798 |
+
target[prop] = value;
|
3799 |
+
continue;
|
3800 |
+
}
|
3801 |
+
running[prop] = animation = new Animation(cfg, target, prop, value);
|
3802 |
+
animations.push(animation);
|
3803 |
+
}
|
3804 |
+
return animations;
|
3805 |
+
}
|
3806 |
+
update(target, values) {
|
3807 |
+
if (this._properties.size === 0) {
|
3808 |
+
Object.assign(target, values);
|
3809 |
+
return;
|
3810 |
+
}
|
3811 |
+
const animations = this._createAnimations(target, values);
|
3812 |
+
if (animations.length) {
|
3813 |
+
animator.add(this._chart, animations);
|
3814 |
+
return true;
|
3815 |
+
}
|
3816 |
+
}
|
3817 |
+
}
|
3818 |
+
function awaitAll(animations, properties) {
|
3819 |
+
const running = [];
|
3820 |
+
const keys = Object.keys(properties);
|
3821 |
+
for (let i = 0; i < keys.length; i++) {
|
3822 |
+
const anim = animations[keys[i]];
|
3823 |
+
if (anim && anim.active()) {
|
3824 |
+
running.push(anim.wait());
|
3825 |
+
}
|
3826 |
+
}
|
3827 |
+
return Promise.all(running);
|
3828 |
+
}
|
3829 |
+
function resolveTargetOptions(target, newOptions) {
|
3830 |
+
if (!newOptions) {
|
3831 |
+
return;
|
3832 |
+
}
|
3833 |
+
let options = target.options;
|
3834 |
+
if (!options) {
|
3835 |
+
target.options = newOptions;
|
3836 |
+
return;
|
3837 |
+
}
|
3838 |
+
if (options.$shared) {
|
3839 |
+
target.options = options = Object.assign({}, options, {$shared: false, $animations: {}});
|
3840 |
+
}
|
3841 |
+
return options;
|
3842 |
+
}
|
3843 |
+
|
3844 |
+
function scaleClip(scale, allowedOverflow) {
|
3845 |
+
const opts = scale && scale.options || {};
|
3846 |
+
const reverse = opts.reverse;
|
3847 |
+
const min = opts.min === undefined ? allowedOverflow : 0;
|
3848 |
+
const max = opts.max === undefined ? allowedOverflow : 0;
|
3849 |
+
return {
|
3850 |
+
start: reverse ? max : min,
|
3851 |
+
end: reverse ? min : max
|
3852 |
+
};
|
3853 |
+
}
|
3854 |
+
function defaultClip(xScale, yScale, allowedOverflow) {
|
3855 |
+
if (allowedOverflow === false) {
|
3856 |
+
return false;
|
3857 |
+
}
|
3858 |
+
const x = scaleClip(xScale, allowedOverflow);
|
3859 |
+
const y = scaleClip(yScale, allowedOverflow);
|
3860 |
+
return {
|
3861 |
+
top: y.end,
|
3862 |
+
right: x.end,
|
3863 |
+
bottom: y.start,
|
3864 |
+
left: x.start
|
3865 |
+
};
|
3866 |
+
}
|
3867 |
+
function toClip(value) {
|
3868 |
+
let t, r, b, l;
|
3869 |
+
if (isObject(value)) {
|
3870 |
+
t = value.top;
|
3871 |
+
r = value.right;
|
3872 |
+
b = value.bottom;
|
3873 |
+
l = value.left;
|
3874 |
+
} else {
|
3875 |
+
t = r = b = l = value;
|
3876 |
+
}
|
3877 |
+
return {
|
3878 |
+
top: t,
|
3879 |
+
right: r,
|
3880 |
+
bottom: b,
|
3881 |
+
left: l,
|
3882 |
+
disabled: value === false
|
3883 |
+
};
|
3884 |
+
}
|
3885 |
+
function getSortedDatasetIndices(chart, filterVisible) {
|
3886 |
+
const keys = [];
|
3887 |
+
const metasets = chart._getSortedDatasetMetas(filterVisible);
|
3888 |
+
let i, ilen;
|
3889 |
+
for (i = 0, ilen = metasets.length; i < ilen; ++i) {
|
3890 |
+
keys.push(metasets[i].index);
|
3891 |
+
}
|
3892 |
+
return keys;
|
3893 |
+
}
|
3894 |
+
function applyStack(stack, value, dsIndex, options = {}) {
|
3895 |
+
const keys = stack.keys;
|
3896 |
+
const singleMode = options.mode === 'single';
|
3897 |
+
let i, ilen, datasetIndex, otherValue;
|
3898 |
+
if (value === null) {
|
3899 |
+
return;
|
3900 |
+
}
|
3901 |
+
for (i = 0, ilen = keys.length; i < ilen; ++i) {
|
3902 |
+
datasetIndex = +keys[i];
|
3903 |
+
if (datasetIndex === dsIndex) {
|
3904 |
+
if (options.all) {
|
3905 |
+
continue;
|
3906 |
+
}
|
3907 |
+
break;
|
3908 |
+
}
|
3909 |
+
otherValue = stack.values[datasetIndex];
|
3910 |
+
if (isNumberFinite(otherValue) && (singleMode || (value === 0 || sign(value) === sign(otherValue)))) {
|
3911 |
+
value += otherValue;
|
3912 |
+
}
|
3913 |
+
}
|
3914 |
+
return value;
|
3915 |
+
}
|
3916 |
+
function convertObjectDataToArray(data) {
|
3917 |
+
const keys = Object.keys(data);
|
3918 |
+
const adata = new Array(keys.length);
|
3919 |
+
let i, ilen, key;
|
3920 |
+
for (i = 0, ilen = keys.length; i < ilen; ++i) {
|
3921 |
+
key = keys[i];
|
3922 |
+
adata[i] = {
|
3923 |
+
x: key,
|
3924 |
+
y: data[key]
|
3925 |
+
};
|
3926 |
+
}
|
3927 |
+
return adata;
|
3928 |
+
}
|
3929 |
+
function isStacked(scale, meta) {
|
3930 |
+
const stacked = scale && scale.options.stacked;
|
3931 |
+
return stacked || (stacked === undefined && meta.stack !== undefined);
|
3932 |
+
}
|
3933 |
+
function getStackKey(indexScale, valueScale, meta) {
|
3934 |
+
return `${indexScale.id}.${valueScale.id}.${meta.stack || meta.type}`;
|
3935 |
+
}
|
3936 |
+
function getUserBounds(scale) {
|
3937 |
+
const {min, max, minDefined, maxDefined} = scale.getUserBounds();
|
3938 |
+
return {
|
3939 |
+
min: minDefined ? min : Number.NEGATIVE_INFINITY,
|
3940 |
+
max: maxDefined ? max : Number.POSITIVE_INFINITY
|
3941 |
+
};
|
3942 |
+
}
|
3943 |
+
function getOrCreateStack(stacks, stackKey, indexValue) {
|
3944 |
+
const subStack = stacks[stackKey] || (stacks[stackKey] = {});
|
3945 |
+
return subStack[indexValue] || (subStack[indexValue] = {});
|
3946 |
+
}
|
3947 |
+
function getLastIndexInStack(stack, vScale, positive, type) {
|
3948 |
+
for (const meta of vScale.getMatchingVisibleMetas(type).reverse()) {
|
3949 |
+
const value = stack[meta.index];
|
3950 |
+
if ((positive && value > 0) || (!positive && value < 0)) {
|
3951 |
+
return meta.index;
|
3952 |
+
}
|
3953 |
+
}
|
3954 |
+
return null;
|
3955 |
+
}
|
3956 |
+
function updateStacks(controller, parsed) {
|
3957 |
+
const {chart, _cachedMeta: meta} = controller;
|
3958 |
+
const stacks = chart._stacks || (chart._stacks = {});
|
3959 |
+
const {iScale, vScale, index: datasetIndex} = meta;
|
3960 |
+
const iAxis = iScale.axis;
|
3961 |
+
const vAxis = vScale.axis;
|
3962 |
+
const key = getStackKey(iScale, vScale, meta);
|
3963 |
+
const ilen = parsed.length;
|
3964 |
+
let stack;
|
3965 |
+
for (let i = 0; i < ilen; ++i) {
|
3966 |
+
const item = parsed[i];
|
3967 |
+
const {[iAxis]: index, [vAxis]: value} = item;
|
3968 |
+
const itemStacks = item._stacks || (item._stacks = {});
|
3969 |
+
stack = itemStacks[vAxis] = getOrCreateStack(stacks, key, index);
|
3970 |
+
stack[datasetIndex] = value;
|
3971 |
+
stack._top = getLastIndexInStack(stack, vScale, true, meta.type);
|
3972 |
+
stack._bottom = getLastIndexInStack(stack, vScale, false, meta.type);
|
3973 |
+
}
|
3974 |
+
}
|
3975 |
+
function getFirstScaleId(chart, axis) {
|
3976 |
+
const scales = chart.scales;
|
3977 |
+
return Object.keys(scales).filter(key => scales[key].axis === axis).shift();
|
3978 |
+
}
|
3979 |
+
function createDatasetContext(parent, index) {
|
3980 |
+
return createContext(parent,
|
3981 |
+
{
|
3982 |
+
active: false,
|
3983 |
+
dataset: undefined,
|
3984 |
+
datasetIndex: index,
|
3985 |
+
index,
|
3986 |
+
mode: 'default',
|
3987 |
+
type: 'dataset'
|
3988 |
+
}
|
3989 |
+
);
|
3990 |
+
}
|
3991 |
+
function createDataContext(parent, index, element) {
|
3992 |
+
return createContext(parent, {
|
3993 |
+
active: false,
|
3994 |
+
dataIndex: index,
|
3995 |
+
parsed: undefined,
|
3996 |
+
raw: undefined,
|
3997 |
+
element,
|
3998 |
+
index,
|
3999 |
+
mode: 'default',
|
4000 |
+
type: 'data'
|
4001 |
+
});
|
4002 |
+
}
|
4003 |
+
function clearStacks(meta, items) {
|
4004 |
+
const datasetIndex = meta.controller.index;
|
4005 |
+
const axis = meta.vScale && meta.vScale.axis;
|
4006 |
+
if (!axis) {
|
4007 |
+
return;
|
4008 |
+
}
|
4009 |
+
items = items || meta._parsed;
|
4010 |
+
for (const parsed of items) {
|
4011 |
+
const stacks = parsed._stacks;
|
4012 |
+
if (!stacks || stacks[axis] === undefined || stacks[axis][datasetIndex] === undefined) {
|
4013 |
+
return;
|
4014 |
+
}
|
4015 |
+
delete stacks[axis][datasetIndex];
|
4016 |
+
}
|
4017 |
+
}
|
4018 |
+
const isDirectUpdateMode = (mode) => mode === 'reset' || mode === 'none';
|
4019 |
+
const cloneIfNotShared = (cached, shared) => shared ? cached : Object.assign({}, cached);
|
4020 |
+
const createStack = (canStack, meta, chart) => canStack && !meta.hidden && meta._stacked
|
4021 |
+
&& {keys: getSortedDatasetIndices(chart, true), values: null};
|
4022 |
+
class DatasetController {
|
4023 |
+
constructor(chart, datasetIndex) {
|
4024 |
+
this.chart = chart;
|
4025 |
+
this._ctx = chart.ctx;
|
4026 |
+
this.index = datasetIndex;
|
4027 |
+
this._cachedDataOpts = {};
|
4028 |
+
this._cachedMeta = this.getMeta();
|
4029 |
+
this._type = this._cachedMeta.type;
|
4030 |
+
this.options = undefined;
|
4031 |
+
this._parsing = false;
|
4032 |
+
this._data = undefined;
|
4033 |
+
this._objectData = undefined;
|
4034 |
+
this._sharedOptions = undefined;
|
4035 |
+
this._drawStart = undefined;
|
4036 |
+
this._drawCount = undefined;
|
4037 |
+
this.enableOptionSharing = false;
|
4038 |
+
this.$context = undefined;
|
4039 |
+
this._syncList = [];
|
4040 |
+
this.initialize();
|
4041 |
+
}
|
4042 |
+
initialize() {
|
4043 |
+
const meta = this._cachedMeta;
|
4044 |
+
this.configure();
|
4045 |
+
this.linkScales();
|
4046 |
+
meta._stacked = isStacked(meta.vScale, meta);
|
4047 |
+
this.addElements();
|
4048 |
+
}
|
4049 |
+
updateIndex(datasetIndex) {
|
4050 |
+
if (this.index !== datasetIndex) {
|
4051 |
+
clearStacks(this._cachedMeta);
|
4052 |
+
}
|
4053 |
+
this.index = datasetIndex;
|
4054 |
+
}
|
4055 |
+
linkScales() {
|
4056 |
+
const chart = this.chart;
|
4057 |
+
const meta = this._cachedMeta;
|
4058 |
+
const dataset = this.getDataset();
|
4059 |
+
const chooseId = (axis, x, y, r) => axis === 'x' ? x : axis === 'r' ? r : y;
|
4060 |
+
const xid = meta.xAxisID = valueOrDefault(dataset.xAxisID, getFirstScaleId(chart, 'x'));
|
4061 |
+
const yid = meta.yAxisID = valueOrDefault(dataset.yAxisID, getFirstScaleId(chart, 'y'));
|
4062 |
+
const rid = meta.rAxisID = valueOrDefault(dataset.rAxisID, getFirstScaleId(chart, 'r'));
|
4063 |
+
const indexAxis = meta.indexAxis;
|
4064 |
+
const iid = meta.iAxisID = chooseId(indexAxis, xid, yid, rid);
|
4065 |
+
const vid = meta.vAxisID = chooseId(indexAxis, yid, xid, rid);
|
4066 |
+
meta.xScale = this.getScaleForId(xid);
|
4067 |
+
meta.yScale = this.getScaleForId(yid);
|
4068 |
+
meta.rScale = this.getScaleForId(rid);
|
4069 |
+
meta.iScale = this.getScaleForId(iid);
|
4070 |
+
meta.vScale = this.getScaleForId(vid);
|
4071 |
+
}
|
4072 |
+
getDataset() {
|
4073 |
+
return this.chart.data.datasets[this.index];
|
4074 |
+
}
|
4075 |
+
getMeta() {
|
4076 |
+
return this.chart.getDatasetMeta(this.index);
|
4077 |
+
}
|
4078 |
+
getScaleForId(scaleID) {
|
4079 |
+
return this.chart.scales[scaleID];
|
4080 |
+
}
|
4081 |
+
_getOtherScale(scale) {
|
4082 |
+
const meta = this._cachedMeta;
|
4083 |
+
return scale === meta.iScale
|
4084 |
+
? meta.vScale
|
4085 |
+
: meta.iScale;
|
4086 |
+
}
|
4087 |
+
reset() {
|
4088 |
+
this._update('reset');
|
4089 |
+
}
|
4090 |
+
_destroy() {
|
4091 |
+
const meta = this._cachedMeta;
|
4092 |
+
if (this._data) {
|
4093 |
+
unlistenArrayEvents(this._data, this);
|
4094 |
+
}
|
4095 |
+
if (meta._stacked) {
|
4096 |
+
clearStacks(meta);
|
4097 |
+
}
|
4098 |
+
}
|
4099 |
+
_dataCheck() {
|
4100 |
+
const dataset = this.getDataset();
|
4101 |
+
const data = dataset.data || (dataset.data = []);
|
4102 |
+
const _data = this._data;
|
4103 |
+
if (isObject(data)) {
|
4104 |
+
this._data = convertObjectDataToArray(data);
|
4105 |
+
} else if (_data !== data) {
|
4106 |
+
if (_data) {
|
4107 |
+
unlistenArrayEvents(_data, this);
|
4108 |
+
const meta = this._cachedMeta;
|
4109 |
+
clearStacks(meta);
|
4110 |
+
meta._parsed = [];
|
4111 |
+
}
|
4112 |
+
if (data && Object.isExtensible(data)) {
|
4113 |
+
listenArrayEvents(data, this);
|
4114 |
+
}
|
4115 |
+
this._syncList = [];
|
4116 |
+
this._data = data;
|
4117 |
+
}
|
4118 |
+
}
|
4119 |
+
addElements() {
|
4120 |
+
const meta = this._cachedMeta;
|
4121 |
+
this._dataCheck();
|
4122 |
+
if (this.datasetElementType) {
|
4123 |
+
meta.dataset = new this.datasetElementType();
|
4124 |
+
}
|
4125 |
+
}
|
4126 |
+
buildOrUpdateElements(resetNewElements) {
|
4127 |
+
const meta = this._cachedMeta;
|
4128 |
+
const dataset = this.getDataset();
|
4129 |
+
let stackChanged = false;
|
4130 |
+
this._dataCheck();
|
4131 |
+
const oldStacked = meta._stacked;
|
4132 |
+
meta._stacked = isStacked(meta.vScale, meta);
|
4133 |
+
if (meta.stack !== dataset.stack) {
|
4134 |
+
stackChanged = true;
|
4135 |
+
clearStacks(meta);
|
4136 |
+
meta.stack = dataset.stack;
|
4137 |
+
}
|
4138 |
+
this._resyncElements(resetNewElements);
|
4139 |
+
if (stackChanged || oldStacked !== meta._stacked) {
|
4140 |
+
updateStacks(this, meta._parsed);
|
4141 |
+
}
|
4142 |
+
}
|
4143 |
+
configure() {
|
4144 |
+
const config = this.chart.config;
|
4145 |
+
const scopeKeys = config.datasetScopeKeys(this._type);
|
4146 |
+
const scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true);
|
4147 |
+
this.options = config.createResolver(scopes, this.getContext());
|
4148 |
+
this._parsing = this.options.parsing;
|
4149 |
+
this._cachedDataOpts = {};
|
4150 |
+
}
|
4151 |
+
parse(start, count) {
|
4152 |
+
const {_cachedMeta: meta, _data: data} = this;
|
4153 |
+
const {iScale, _stacked} = meta;
|
4154 |
+
const iAxis = iScale.axis;
|
4155 |
+
let sorted = start === 0 && count === data.length ? true : meta._sorted;
|
4156 |
+
let prev = start > 0 && meta._parsed[start - 1];
|
4157 |
+
let i, cur, parsed;
|
4158 |
+
if (this._parsing === false) {
|
4159 |
+
meta._parsed = data;
|
4160 |
+
meta._sorted = true;
|
4161 |
+
parsed = data;
|
4162 |
+
} else {
|
4163 |
+
if (isArray(data[start])) {
|
4164 |
+
parsed = this.parseArrayData(meta, data, start, count);
|
4165 |
+
} else if (isObject(data[start])) {
|
4166 |
+
parsed = this.parseObjectData(meta, data, start, count);
|
4167 |
+
} else {
|
4168 |
+
parsed = this.parsePrimitiveData(meta, data, start, count);
|
4169 |
+
}
|
4170 |
+
const isNotInOrderComparedToPrev = () => cur[iAxis] === null || (prev && cur[iAxis] < prev[iAxis]);
|
4171 |
+
for (i = 0; i < count; ++i) {
|
4172 |
+
meta._parsed[i + start] = cur = parsed[i];
|
4173 |
+
if (sorted) {
|
4174 |
+
if (isNotInOrderComparedToPrev()) {
|
4175 |
+
sorted = false;
|
4176 |
+
}
|
4177 |
+
prev = cur;
|
4178 |
}
|
4179 |
+
}
|
4180 |
+
meta._sorted = sorted;
|
4181 |
+
}
|
4182 |
+
if (_stacked) {
|
4183 |
+
updateStacks(this, parsed);
|
4184 |
+
}
|
4185 |
+
}
|
4186 |
+
parsePrimitiveData(meta, data, start, count) {
|
4187 |
+
const {iScale, vScale} = meta;
|
4188 |
+
const iAxis = iScale.axis;
|
4189 |
+
const vAxis = vScale.axis;
|
4190 |
+
const labels = iScale.getLabels();
|
4191 |
+
const singleScale = iScale === vScale;
|
4192 |
+
const parsed = new Array(count);
|
4193 |
+
let i, ilen, index;
|
4194 |
+
for (i = 0, ilen = count; i < ilen; ++i) {
|
4195 |
+
index = i + start;
|
4196 |
+
parsed[i] = {
|
4197 |
+
[iAxis]: singleScale || iScale.parse(labels[index], index),
|
4198 |
+
[vAxis]: vScale.parse(data[index], index)
|
4199 |
+
};
|
4200 |
+
}
|
4201 |
+
return parsed;
|
4202 |
+
}
|
4203 |
+
parseArrayData(meta, data, start, count) {
|
4204 |
+
const {xScale, yScale} = meta;
|
4205 |
+
const parsed = new Array(count);
|
4206 |
+
let i, ilen, index, item;
|
4207 |
+
for (i = 0, ilen = count; i < ilen; ++i) {
|
4208 |
+
index = i + start;
|
4209 |
+
item = data[index];
|
4210 |
+
parsed[i] = {
|
4211 |
+
x: xScale.parse(item[0], index),
|
4212 |
+
y: yScale.parse(item[1], index)
|
4213 |
+
};
|
4214 |
+
}
|
4215 |
+
return parsed;
|
4216 |
+
}
|
4217 |
+
parseObjectData(meta, data, start, count) {
|
4218 |
+
const {xScale, yScale} = meta;
|
4219 |
+
const {xAxisKey = 'x', yAxisKey = 'y'} = this._parsing;
|
4220 |
+
const parsed = new Array(count);
|
4221 |
+
let i, ilen, index, item;
|
4222 |
+
for (i = 0, ilen = count; i < ilen; ++i) {
|
4223 |
+
index = i + start;
|
4224 |
+
item = data[index];
|
4225 |
+
parsed[i] = {
|
4226 |
+
x: xScale.parse(resolveObjectKey(item, xAxisKey), index),
|
4227 |
+
y: yScale.parse(resolveObjectKey(item, yAxisKey), index)
|
4228 |
+
};
|
4229 |
+
}
|
4230 |
+
return parsed;
|
4231 |
+
}
|
4232 |
+
getParsed(index) {
|
4233 |
+
return this._cachedMeta._parsed[index];
|
4234 |
+
}
|
4235 |
+
getDataElement(index) {
|
4236 |
+
return this._cachedMeta.data[index];
|
4237 |
+
}
|
4238 |
+
applyStack(scale, parsed, mode) {
|
4239 |
+
const chart = this.chart;
|
4240 |
+
const meta = this._cachedMeta;
|
4241 |
+
const value = parsed[scale.axis];
|
4242 |
+
const stack = {
|
4243 |
+
keys: getSortedDatasetIndices(chart, true),
|
4244 |
+
values: parsed._stacks[scale.axis]
|
4245 |
+
};
|
4246 |
+
return applyStack(stack, value, meta.index, {mode});
|
4247 |
+
}
|
4248 |
+
updateRangeFromParsed(range, scale, parsed, stack) {
|
4249 |
+
const parsedValue = parsed[scale.axis];
|
4250 |
+
let value = parsedValue === null ? NaN : parsedValue;
|
4251 |
+
const values = stack && parsed._stacks[scale.axis];
|
4252 |
+
if (stack && values) {
|
4253 |
+
stack.values = values;
|
4254 |
+
value = applyStack(stack, parsedValue, this._cachedMeta.index);
|
4255 |
+
}
|
4256 |
+
range.min = Math.min(range.min, value);
|
4257 |
+
range.max = Math.max(range.max, value);
|
4258 |
+
}
|
4259 |
+
getMinMax(scale, canStack) {
|
4260 |
+
const meta = this._cachedMeta;
|
4261 |
+
const _parsed = meta._parsed;
|
4262 |
+
const sorted = meta._sorted && scale === meta.iScale;
|
4263 |
+
const ilen = _parsed.length;
|
4264 |
+
const otherScale = this._getOtherScale(scale);
|
4265 |
+
const stack = createStack(canStack, meta, this.chart);
|
4266 |
+
const range = {min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY};
|
4267 |
+
const {min: otherMin, max: otherMax} = getUserBounds(otherScale);
|
4268 |
+
let i, parsed;
|
4269 |
+
function _skip() {
|
4270 |
+
parsed = _parsed[i];
|
4271 |
+
const otherValue = parsed[otherScale.axis];
|
4272 |
+
return !isNumberFinite(parsed[scale.axis]) || otherMin > otherValue || otherMax < otherValue;
|
4273 |
+
}
|
4274 |
+
for (i = 0; i < ilen; ++i) {
|
4275 |
+
if (_skip()) {
|
4276 |
+
continue;
|
4277 |
+
}
|
4278 |
+
this.updateRangeFromParsed(range, scale, parsed, stack);
|
4279 |
+
if (sorted) {
|
4280 |
+
break;
|
4281 |
+
}
|
4282 |
+
}
|
4283 |
+
if (sorted) {
|
4284 |
+
for (i = ilen - 1; i >= 0; --i) {
|
4285 |
+
if (_skip()) {
|
4286 |
+
continue;
|
4287 |
}
|
4288 |
+
this.updateRangeFromParsed(range, scale, parsed, stack);
|
4289 |
+
break;
|
4290 |
+
}
|
4291 |
+
}
|
4292 |
+
return range;
|
4293 |
+
}
|
4294 |
+
getAllParsedValues(scale) {
|
4295 |
+
const parsed = this._cachedMeta._parsed;
|
4296 |
+
const values = [];
|
4297 |
+
let i, ilen, value;
|
4298 |
+
for (i = 0, ilen = parsed.length; i < ilen; ++i) {
|
4299 |
+
value = parsed[i][scale.axis];
|
4300 |
+
if (isNumberFinite(value)) {
|
4301 |
+
values.push(value);
|
4302 |
+
}
|
4303 |
+
}
|
4304 |
+
return values;
|
4305 |
+
}
|
4306 |
+
getMaxOverflow() {
|
4307 |
+
return false;
|
4308 |
+
}
|
4309 |
+
getLabelAndValue(index) {
|
4310 |
+
const meta = this._cachedMeta;
|
4311 |
+
const iScale = meta.iScale;
|
4312 |
+
const vScale = meta.vScale;
|
4313 |
+
const parsed = this.getParsed(index);
|
4314 |
+
return {
|
4315 |
+
label: iScale ? '' + iScale.getLabelForValue(parsed[iScale.axis]) : '',
|
4316 |
+
value: vScale ? '' + vScale.getLabelForValue(parsed[vScale.axis]) : ''
|
4317 |
+
};
|
4318 |
+
}
|
4319 |
+
_update(mode) {
|
4320 |
+
const meta = this._cachedMeta;
|
4321 |
+
this.update(mode || 'default');
|
4322 |
+
meta._clip = toClip(valueOrDefault(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow())));
|
4323 |
+
}
|
4324 |
+
update(mode) {}
|
4325 |
+
draw() {
|
4326 |
+
const ctx = this._ctx;
|
4327 |
+
const chart = this.chart;
|
4328 |
+
const meta = this._cachedMeta;
|
4329 |
+
const elements = meta.data || [];
|
4330 |
+
const area = chart.chartArea;
|
4331 |
+
const active = [];
|
4332 |
+
const start = this._drawStart || 0;
|
4333 |
+
const count = this._drawCount || (elements.length - start);
|
4334 |
+
const drawActiveElementsOnTop = this.options.drawActiveElementsOnTop;
|
4335 |
+
let i;
|
4336 |
+
if (meta.dataset) {
|
4337 |
+
meta.dataset.draw(ctx, area, start, count);
|
4338 |
+
}
|
4339 |
+
for (i = start; i < start + count; ++i) {
|
4340 |
+
const element = elements[i];
|
4341 |
+
if (element.hidden) {
|
4342 |
+
continue;
|
4343 |
+
}
|
4344 |
+
if (element.active && drawActiveElementsOnTop) {
|
4345 |
+
active.push(element);
|
4346 |
+
} else {
|
4347 |
+
element.draw(ctx, area);
|
4348 |
+
}
|
4349 |
+
}
|
4350 |
+
for (i = 0; i < active.length; ++i) {
|
4351 |
+
active[i].draw(ctx, area);
|
4352 |
+
}
|
4353 |
+
}
|
4354 |
+
getStyle(index, active) {
|
4355 |
+
const mode = active ? 'active' : 'default';
|
4356 |
+
return index === undefined && this._cachedMeta.dataset
|
4357 |
+
? this.resolveDatasetElementOptions(mode)
|
4358 |
+
: this.resolveDataElementOptions(index || 0, mode);
|
4359 |
+
}
|
4360 |
+
getContext(index, active, mode) {
|
4361 |
+
const dataset = this.getDataset();
|
4362 |
+
let context;
|
4363 |
+
if (index >= 0 && index < this._cachedMeta.data.length) {
|
4364 |
+
const element = this._cachedMeta.data[index];
|
4365 |
+
context = element.$context ||
|
4366 |
+
(element.$context = createDataContext(this.getContext(), index, element));
|
4367 |
+
context.parsed = this.getParsed(index);
|
4368 |
+
context.raw = dataset.data[index];
|
4369 |
+
context.index = context.dataIndex = index;
|
4370 |
+
} else {
|
4371 |
+
context = this.$context ||
|
4372 |
+
(this.$context = createDatasetContext(this.chart.getContext(), this.index));
|
4373 |
+
context.dataset = dataset;
|
4374 |
+
context.index = context.datasetIndex = this.index;
|
4375 |
+
}
|
4376 |
+
context.active = !!active;
|
4377 |
+
context.mode = mode;
|
4378 |
+
return context;
|
4379 |
+
}
|
4380 |
+
resolveDatasetElementOptions(mode) {
|
4381 |
+
return this._resolveElementOptions(this.datasetElementType.id, mode);
|
4382 |
+
}
|
4383 |
+
resolveDataElementOptions(index, mode) {
|
4384 |
+
return this._resolveElementOptions(this.dataElementType.id, mode, index);
|
4385 |
+
}
|
4386 |
+
_resolveElementOptions(elementType, mode = 'default', index) {
|
4387 |
+
const active = mode === 'active';
|
4388 |
+
const cache = this._cachedDataOpts;
|
4389 |
+
const cacheKey = elementType + '-' + mode;
|
4390 |
+
const cached = cache[cacheKey];
|
4391 |
+
const sharing = this.enableOptionSharing && defined(index);
|
4392 |
+
if (cached) {
|
4393 |
+
return cloneIfNotShared(cached, sharing);
|
4394 |
+
}
|
4395 |
+
const config = this.chart.config;
|
4396 |
+
const scopeKeys = config.datasetElementScopeKeys(this._type, elementType);
|
4397 |
+
const prefixes = active ? [`${elementType}Hover`, 'hover', elementType, ''] : [elementType, ''];
|
4398 |
+
const scopes = config.getOptionScopes(this.getDataset(), scopeKeys);
|
4399 |
+
const names = Object.keys(defaults.elements[elementType]);
|
4400 |
+
const context = () => this.getContext(index, active);
|
4401 |
+
const values = config.resolveNamedOptions(scopes, names, context, prefixes);
|
4402 |
+
if (values.$shared) {
|
4403 |
+
values.$shared = sharing;
|
4404 |
+
cache[cacheKey] = Object.freeze(cloneIfNotShared(values, sharing));
|
4405 |
+
}
|
4406 |
+
return values;
|
4407 |
+
}
|
4408 |
+
_resolveAnimations(index, transition, active) {
|
4409 |
+
const chart = this.chart;
|
4410 |
+
const cache = this._cachedDataOpts;
|
4411 |
+
const cacheKey = `animation-${transition}`;
|
4412 |
+
const cached = cache[cacheKey];
|
4413 |
+
if (cached) {
|
4414 |
+
return cached;
|
4415 |
+
}
|
4416 |
+
let options;
|
4417 |
+
if (chart.options.animation !== false) {
|
4418 |
+
const config = this.chart.config;
|
4419 |
+
const scopeKeys = config.datasetAnimationScopeKeys(this._type, transition);
|
4420 |
+
const scopes = config.getOptionScopes(this.getDataset(), scopeKeys);
|
4421 |
+
options = config.createResolver(scopes, this.getContext(index, active, transition));
|
4422 |
+
}
|
4423 |
+
const animations = new Animations(chart, options && options.animations);
|
4424 |
+
if (options && options._cacheable) {
|
4425 |
+
cache[cacheKey] = Object.freeze(animations);
|
4426 |
+
}
|
4427 |
+
return animations;
|
4428 |
+
}
|
4429 |
+
getSharedOptions(options) {
|
4430 |
+
if (!options.$shared) {
|
4431 |
+
return;
|
4432 |
+
}
|
4433 |
+
return this._sharedOptions || (this._sharedOptions = Object.assign({}, options));
|
4434 |
+
}
|
4435 |
+
includeOptions(mode, sharedOptions) {
|
4436 |
+
return !sharedOptions || isDirectUpdateMode(mode) || this.chart._animationsDisabled;
|
4437 |
+
}
|
4438 |
+
updateElement(element, index, properties, mode) {
|
4439 |
+
if (isDirectUpdateMode(mode)) {
|
4440 |
+
Object.assign(element, properties);
|
4441 |
+
} else {
|
4442 |
+
this._resolveAnimations(index, mode).update(element, properties);
|
4443 |
+
}
|
4444 |
+
}
|
4445 |
+
updateSharedOptions(sharedOptions, mode, newOptions) {
|
4446 |
+
if (sharedOptions && !isDirectUpdateMode(mode)) {
|
4447 |
+
this._resolveAnimations(undefined, mode).update(sharedOptions, newOptions);
|
4448 |
+
}
|
4449 |
+
}
|
4450 |
+
_setStyle(element, index, mode, active) {
|
4451 |
+
element.active = active;
|
4452 |
+
const options = this.getStyle(index, active);
|
4453 |
+
this._resolveAnimations(index, mode, active).update(element, {
|
4454 |
+
options: (!active && this.getSharedOptions(options)) || options
|
4455 |
+
});
|
4456 |
+
}
|
4457 |
+
removeHoverStyle(element, datasetIndex, index) {
|
4458 |
+
this._setStyle(element, index, 'active', false);
|
4459 |
+
}
|
4460 |
+
setHoverStyle(element, datasetIndex, index) {
|
4461 |
+
this._setStyle(element, index, 'active', true);
|
4462 |
+
}
|
4463 |
+
_removeDatasetHoverStyle() {
|
4464 |
+
const element = this._cachedMeta.dataset;
|
4465 |
+
if (element) {
|
4466 |
+
this._setStyle(element, undefined, 'active', false);
|
4467 |
+
}
|
4468 |
+
}
|
4469 |
+
_setDatasetHoverStyle() {
|
4470 |
+
const element = this._cachedMeta.dataset;
|
4471 |
+
if (element) {
|
4472 |
+
this._setStyle(element, undefined, 'active', true);
|
4473 |
+
}
|
4474 |
+
}
|
4475 |
+
_resyncElements(resetNewElements) {
|
4476 |
+
const data = this._data;
|
4477 |
+
const elements = this._cachedMeta.data;
|
4478 |
+
for (const [method, arg1, arg2] of this._syncList) {
|
4479 |
+
this[method](arg1, arg2);
|
4480 |
+
}
|
4481 |
+
this._syncList = [];
|
4482 |
+
const numMeta = elements.length;
|
4483 |
+
const numData = data.length;
|
4484 |
+
const count = Math.min(numData, numMeta);
|
4485 |
+
if (count) {
|
4486 |
+
this.parse(0, count);
|
4487 |
+
}
|
4488 |
+
if (numData > numMeta) {
|
4489 |
+
this._insertElements(numMeta, numData - numMeta, resetNewElements);
|
4490 |
+
} else if (numData < numMeta) {
|
4491 |
+
this._removeElements(numData, numMeta - numData);
|
4492 |
+
}
|
4493 |
+
}
|
4494 |
+
_insertElements(start, count, resetNewElements = true) {
|
4495 |
+
const meta = this._cachedMeta;
|
4496 |
+
const data = meta.data;
|
4497 |
+
const end = start + count;
|
4498 |
+
let i;
|
4499 |
+
const move = (arr) => {
|
4500 |
+
arr.length += count;
|
4501 |
+
for (i = arr.length - 1; i >= end; i--) {
|
4502 |
+
arr[i] = arr[i - count];
|
4503 |
+
}
|
4504 |
+
};
|
4505 |
+
move(data);
|
4506 |
+
for (i = start; i < end; ++i) {
|
4507 |
+
data[i] = new this.dataElementType();
|
4508 |
+
}
|
4509 |
+
if (this._parsing) {
|
4510 |
+
move(meta._parsed);
|
4511 |
+
}
|
4512 |
+
this.parse(start, count);
|
4513 |
+
if (resetNewElements) {
|
4514 |
+
this.updateElements(data, start, count, 'reset');
|
4515 |
+
}
|
4516 |
+
}
|
4517 |
+
updateElements(element, start, count, mode) {}
|
4518 |
+
_removeElements(start, count) {
|
4519 |
+
const meta = this._cachedMeta;
|
4520 |
+
if (this._parsing) {
|
4521 |
+
const removed = meta._parsed.splice(start, count);
|
4522 |
+
if (meta._stacked) {
|
4523 |
+
clearStacks(meta, removed);
|
4524 |
+
}
|
4525 |
+
}
|
4526 |
+
meta.data.splice(start, count);
|
4527 |
+
}
|
4528 |
+
_sync(args) {
|
4529 |
+
if (this._parsing) {
|
4530 |
+
this._syncList.push(args);
|
4531 |
+
} else {
|
4532 |
+
const [method, arg1, arg2] = args;
|
4533 |
+
this[method](arg1, arg2);
|
4534 |
+
}
|
4535 |
+
this.chart._dataChanges.push([this.index, ...args]);
|
4536 |
+
}
|
4537 |
+
_onDataPush() {
|
4538 |
+
const count = arguments.length;
|
4539 |
+
this._sync(['_insertElements', this.getDataset().data.length - count, count]);
|
4540 |
+
}
|
4541 |
+
_onDataPop() {
|
4542 |
+
this._sync(['_removeElements', this._cachedMeta.data.length - 1, 1]);
|
4543 |
+
}
|
4544 |
+
_onDataShift() {
|
4545 |
+
this._sync(['_removeElements', 0, 1]);
|
4546 |
+
}
|
4547 |
+
_onDataSplice(start, count) {
|
4548 |
+
if (count) {
|
4549 |
+
this._sync(['_removeElements', start, count]);
|
4550 |
+
}
|
4551 |
+
const newCount = arguments.length - 2;
|
4552 |
+
if (newCount) {
|
4553 |
+
this._sync(['_insertElements', start, newCount]);
|
4554 |
+
}
|
4555 |
+
}
|
4556 |
+
_onDataUnshift() {
|
4557 |
+
this._sync(['_insertElements', 0, arguments.length]);
|
4558 |
+
}
|
4559 |
+
}
|
4560 |
+
DatasetController.defaults = {};
|
4561 |
+
DatasetController.prototype.datasetElementType = null;
|
4562 |
+
DatasetController.prototype.dataElementType = null;
|
4563 |
+
|
4564 |
+
class Element {
|
4565 |
+
constructor() {
|
4566 |
+
this.x = undefined;
|
4567 |
+
this.y = undefined;
|
4568 |
+
this.active = false;
|
4569 |
+
this.options = undefined;
|
4570 |
+
this.$animations = undefined;
|
4571 |
+
}
|
4572 |
+
tooltipPosition(useFinalPosition) {
|
4573 |
+
const {x, y} = this.getProps(['x', 'y'], useFinalPosition);
|
4574 |
+
return {x, y};
|
4575 |
+
}
|
4576 |
+
hasValue() {
|
4577 |
+
return isNumber(this.x) && isNumber(this.y);
|
4578 |
+
}
|
4579 |
+
getProps(props, final) {
|
4580 |
+
const anims = this.$animations;
|
4581 |
+
if (!final || !anims) {
|
4582 |
+
return this;
|
4583 |
+
}
|
4584 |
+
const ret = {};
|
4585 |
+
props.forEach(prop => {
|
4586 |
+
ret[prop] = anims[prop] && anims[prop].active() ? anims[prop]._to : this[prop];
|
4587 |
+
});
|
4588 |
+
return ret;
|
4589 |
+
}
|
4590 |
+
}
|
4591 |
+
Element.defaults = {};
|
4592 |
+
Element.defaultRoutes = undefined;
|
4593 |
+
|
4594 |
+
const formatters = {
|
4595 |
+
values(value) {
|
4596 |
+
return isArray(value) ? value : '' + value;
|
4597 |
+
},
|
4598 |
+
numeric(tickValue, index, ticks) {
|
4599 |
+
if (tickValue === 0) {
|
4600 |
+
return '0';
|
4601 |
+
}
|
4602 |
+
const locale = this.chart.options.locale;
|
4603 |
+
let notation;
|
4604 |
+
let delta = tickValue;
|
4605 |
+
if (ticks.length > 1) {
|
4606 |
+
const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
|
4607 |
+
if (maxTick < 1e-4 || maxTick > 1e+15) {
|
4608 |
+
notation = 'scientific';
|
4609 |
+
}
|
4610 |
+
delta = calculateDelta(tickValue, ticks);
|
4611 |
+
}
|
4612 |
+
const logDelta = log10(Math.abs(delta));
|
4613 |
+
const numDecimal = Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0);
|
4614 |
+
const options = {notation, minimumFractionDigits: numDecimal, maximumFractionDigits: numDecimal};
|
4615 |
+
Object.assign(options, this.options.ticks.format);
|
4616 |
+
return formatNumber(tickValue, locale, options);
|
4617 |
+
},
|
4618 |
+
logarithmic(tickValue, index, ticks) {
|
4619 |
+
if (tickValue === 0) {
|
4620 |
+
return '0';
|
4621 |
+
}
|
4622 |
+
const remain = tickValue / (Math.pow(10, Math.floor(log10(tickValue))));
|
4623 |
+
if (remain === 1 || remain === 2 || remain === 5) {
|
4624 |
+
return formatters.numeric.call(this, tickValue, index, ticks);
|
4625 |
+
}
|
4626 |
+
return '';
|
4627 |
+
}
|
4628 |
+
};
|
4629 |
+
function calculateDelta(tickValue, ticks) {
|
4630 |
+
let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
|
4631 |
+
if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) {
|
4632 |
+
delta = tickValue - Math.floor(tickValue);
|
4633 |
+
}
|
4634 |
+
return delta;
|
4635 |
+
}
|
4636 |
+
var Ticks = {formatters};
|
4637 |
+
|
4638 |
+
defaults.set('scale', {
|
4639 |
+
display: true,
|
4640 |
+
offset: false,
|
4641 |
+
reverse: false,
|
4642 |
+
beginAtZero: false,
|
4643 |
+
bounds: 'ticks',
|
4644 |
+
grace: 0,
|
4645 |
+
grid: {
|
4646 |
+
display: true,
|
4647 |
+
lineWidth: 1,
|
4648 |
+
drawBorder: true,
|
4649 |
+
drawOnChartArea: true,
|
4650 |
+
drawTicks: true,
|
4651 |
+
tickLength: 8,
|
4652 |
+
tickWidth: (_ctx, options) => options.lineWidth,
|
4653 |
+
tickColor: (_ctx, options) => options.color,
|
4654 |
+
offset: false,
|
4655 |
+
borderDash: [],
|
4656 |
+
borderDashOffset: 0.0,
|
4657 |
+
borderWidth: 1
|
4658 |
+
},
|
4659 |
+
title: {
|
4660 |
+
display: false,
|
4661 |
+
text: '',
|
4662 |
+
padding: {
|
4663 |
+
top: 4,
|
4664 |
+
bottom: 4
|
4665 |
+
}
|
4666 |
+
},
|
4667 |
+
ticks: {
|
4668 |
+
minRotation: 0,
|
4669 |
+
maxRotation: 50,
|
4670 |
+
mirror: false,
|
4671 |
+
textStrokeWidth: 0,
|
4672 |
+
textStrokeColor: '',
|
4673 |
+
padding: 3,
|
4674 |
+
display: true,
|
4675 |
+
autoSkip: true,
|
4676 |
+
autoSkipPadding: 3,
|
4677 |
+
labelOffset: 0,
|
4678 |
+
callback: Ticks.formatters.values,
|
4679 |
+
minor: {},
|
4680 |
+
major: {},
|
4681 |
+
align: 'center',
|
4682 |
+
crossAlign: 'near',
|
4683 |
+
showLabelBackdrop: false,
|
4684 |
+
backdropColor: 'rgba(255, 255, 255, 0.75)',
|
4685 |
+
backdropPadding: 2,
|
4686 |
+
}
|
4687 |
+
});
|
4688 |
+
defaults.route('scale.ticks', 'color', '', 'color');
|
4689 |
+
defaults.route('scale.grid', 'color', '', 'borderColor');
|
4690 |
+
defaults.route('scale.grid', 'borderColor', '', 'borderColor');
|
4691 |
+
defaults.route('scale.title', 'color', '', 'color');
|
4692 |
+
defaults.describe('scale', {
|
4693 |
+
_fallback: false,
|
4694 |
+
_scriptable: (name) => !name.startsWith('before') && !name.startsWith('after') && name !== 'callback' && name !== 'parser',
|
4695 |
+
_indexable: (name) => name !== 'borderDash' && name !== 'tickBorderDash',
|
4696 |
+
});
|
4697 |
+
defaults.describe('scales', {
|
4698 |
+
_fallback: 'scale',
|
4699 |
+
});
|
4700 |
+
defaults.describe('scale.ticks', {
|
4701 |
+
_scriptable: (name) => name !== 'backdropPadding' && name !== 'callback',
|
4702 |
+
_indexable: (name) => name !== 'backdropPadding',
|
4703 |
+
});
|
4704 |
+
|
4705 |
+
function autoSkip(scale, ticks) {
|
4706 |
+
const tickOpts = scale.options.ticks;
|
4707 |
+
const ticksLimit = tickOpts.maxTicksLimit || determineMaxTicks(scale);
|
4708 |
+
const majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : [];
|
4709 |
+
const numMajorIndices = majorIndices.length;
|
4710 |
+
const first = majorIndices[0];
|
4711 |
+
const last = majorIndices[numMajorIndices - 1];
|
4712 |
+
const newTicks = [];
|
4713 |
+
if (numMajorIndices > ticksLimit) {
|
4714 |
+
skipMajors(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit);
|
4715 |
+
return newTicks;
|
4716 |
+
}
|
4717 |
+
const spacing = calculateSpacing(majorIndices, ticks, ticksLimit);
|
4718 |
+
if (numMajorIndices > 0) {
|
4719 |
+
let i, ilen;
|
4720 |
+
const avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null;
|
4721 |
+
skip(ticks, newTicks, spacing, isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first);
|
4722 |
+
for (i = 0, ilen = numMajorIndices - 1; i < ilen; i++) {
|
4723 |
+
skip(ticks, newTicks, spacing, majorIndices[i], majorIndices[i + 1]);
|
4724 |
+
}
|
4725 |
+
skip(ticks, newTicks, spacing, last, isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing);
|
4726 |
+
return newTicks;
|
4727 |
+
}
|
4728 |
+
skip(ticks, newTicks, spacing);
|
4729 |
+
return newTicks;
|
4730 |
+
}
|
4731 |
+
function determineMaxTicks(scale) {
|
4732 |
+
const offset = scale.options.offset;
|
4733 |
+
const tickLength = scale._tickSize();
|
4734 |
+
const maxScale = scale._length / tickLength + (offset ? 0 : 1);
|
4735 |
+
const maxChart = scale._maxLength / tickLength;
|
4736 |
+
return Math.floor(Math.min(maxScale, maxChart));
|
4737 |
+
}
|
4738 |
+
function calculateSpacing(majorIndices, ticks, ticksLimit) {
|
4739 |
+
const evenMajorSpacing = getEvenSpacing(majorIndices);
|
4740 |
+
const spacing = ticks.length / ticksLimit;
|
4741 |
+
if (!evenMajorSpacing) {
|
4742 |
+
return Math.max(spacing, 1);
|
4743 |
+
}
|
4744 |
+
const factors = _factorize(evenMajorSpacing);
|
4745 |
+
for (let i = 0, ilen = factors.length - 1; i < ilen; i++) {
|
4746 |
+
const factor = factors[i];
|
4747 |
+
if (factor > spacing) {
|
4748 |
+
return factor;
|
4749 |
+
}
|
4750 |
+
}
|
4751 |
+
return Math.max(spacing, 1);
|
4752 |
+
}
|
4753 |
+
function getMajorIndices(ticks) {
|
4754 |
+
const result = [];
|
4755 |
+
let i, ilen;
|
4756 |
+
for (i = 0, ilen = ticks.length; i < ilen; i++) {
|
4757 |
+
if (ticks[i].major) {
|
4758 |
+
result.push(i);
|
4759 |
+
}
|
4760 |
+
}
|
4761 |
+
return result;
|
4762 |
+
}
|
4763 |
+
function skipMajors(ticks, newTicks, majorIndices, spacing) {
|
4764 |
+
let count = 0;
|
4765 |
+
let next = majorIndices[0];
|
4766 |
+
let i;
|
4767 |
+
spacing = Math.ceil(spacing);
|
4768 |
+
for (i = 0; i < ticks.length; i++) {
|
4769 |
+
if (i === next) {
|
4770 |
+
newTicks.push(ticks[i]);
|
4771 |
+
count++;
|
4772 |
+
next = majorIndices[count * spacing];
|
4773 |
+
}
|
4774 |
+
}
|
4775 |
+
}
|
4776 |
+
function skip(ticks, newTicks, spacing, majorStart, majorEnd) {
|
4777 |
+
const start = valueOrDefault(majorStart, 0);
|
4778 |
+
const end = Math.min(valueOrDefault(majorEnd, ticks.length), ticks.length);
|
4779 |
+
let count = 0;
|
4780 |
+
let length, i, next;
|
4781 |
+
spacing = Math.ceil(spacing);
|
4782 |
+
if (majorEnd) {
|
4783 |
+
length = majorEnd - majorStart;
|
4784 |
+
spacing = length / Math.floor(length / spacing);
|
4785 |
+
}
|
4786 |
+
next = start;
|
4787 |
+
while (next < 0) {
|
4788 |
+
count++;
|
4789 |
+
next = Math.round(start + count * spacing);
|
4790 |
+
}
|
4791 |
+
for (i = Math.max(start, 0); i < end; i++) {
|
4792 |
+
if (i === next) {
|
4793 |
+
newTicks.push(ticks[i]);
|
4794 |
+
count++;
|
4795 |
+
next = Math.round(start + count * spacing);
|
4796 |
+
}
|
4797 |
+
}
|
4798 |
+
}
|
4799 |
+
function getEvenSpacing(arr) {
|
4800 |
+
const len = arr.length;
|
4801 |
+
let i, diff;
|
4802 |
+
if (len < 2) {
|
4803 |
+
return false;
|
4804 |
+
}
|
4805 |
+
for (diff = arr[0], i = 1; i < len; ++i) {
|
4806 |
+
if (arr[i] - arr[i - 1] !== diff) {
|
4807 |
+
return false;
|
4808 |
+
}
|
4809 |
+
}
|
4810 |
+
return diff;
|
4811 |
+
}
|
4812 |
+
|
4813 |
+
const reverseAlign = (align) => align === 'left' ? 'right' : align === 'right' ? 'left' : align;
|
4814 |
+
const offsetFromEdge = (scale, edge, offset) => edge === 'top' || edge === 'left' ? scale[edge] + offset : scale[edge] - offset;
|
4815 |
+
function sample(arr, numItems) {
|
4816 |
+
const result = [];
|
4817 |
+
const increment = arr.length / numItems;
|
4818 |
+
const len = arr.length;
|
4819 |
+
let i = 0;
|
4820 |
+
for (; i < len; i += increment) {
|
4821 |
+
result.push(arr[Math.floor(i)]);
|
4822 |
+
}
|
4823 |
+
return result;
|
4824 |
+
}
|
4825 |
+
function getPixelForGridLine(scale, index, offsetGridLines) {
|
4826 |
+
const length = scale.ticks.length;
|
4827 |
+
const validIndex = Math.min(index, length - 1);
|
4828 |
+
const start = scale._startPixel;
|
4829 |
+
const end = scale._endPixel;
|
4830 |
+
const epsilon = 1e-6;
|
4831 |
+
let lineValue = scale.getPixelForTick(validIndex);
|
4832 |
+
let offset;
|
4833 |
+
if (offsetGridLines) {
|
4834 |
+
if (length === 1) {
|
4835 |
+
offset = Math.max(lineValue - start, end - lineValue);
|
4836 |
+
} else if (index === 0) {
|
4837 |
+
offset = (scale.getPixelForTick(1) - lineValue) / 2;
|
4838 |
+
} else {
|
4839 |
+
offset = (lineValue - scale.getPixelForTick(validIndex - 1)) / 2;
|
4840 |
+
}
|
4841 |
+
lineValue += validIndex < index ? offset : -offset;
|
4842 |
+
if (lineValue < start - epsilon || lineValue > end + epsilon) {
|
4843 |
+
return;
|
4844 |
+
}
|
4845 |
+
}
|
4846 |
+
return lineValue;
|
4847 |
+
}
|
4848 |
+
function garbageCollect(caches, length) {
|
4849 |
+
each(caches, (cache) => {
|
4850 |
+
const gc = cache.gc;
|
4851 |
+
const gcLen = gc.length / 2;
|
4852 |
+
let i;
|
4853 |
+
if (gcLen > length) {
|
4854 |
+
for (i = 0; i < gcLen; ++i) {
|
4855 |
+
delete cache.data[gc[i]];
|
4856 |
+
}
|
4857 |
+
gc.splice(0, gcLen);
|
4858 |
+
}
|
4859 |
+
});
|
4860 |
+
}
|
4861 |
+
function getTickMarkLength(options) {
|
4862 |
+
return options.drawTicks ? options.tickLength : 0;
|
4863 |
+
}
|
4864 |
+
function getTitleHeight(options, fallback) {
|
4865 |
+
if (!options.display) {
|
4866 |
+
return 0;
|
4867 |
+
}
|
4868 |
+
const font = toFont(options.font, fallback);
|
4869 |
+
const padding = toPadding(options.padding);
|
4870 |
+
const lines = isArray(options.text) ? options.text.length : 1;
|
4871 |
+
return (lines * font.lineHeight) + padding.height;
|
4872 |
+
}
|
4873 |
+
function createScaleContext(parent, scale) {
|
4874 |
+
return createContext(parent, {
|
4875 |
+
scale,
|
4876 |
+
type: 'scale'
|
4877 |
+
});
|
4878 |
+
}
|
4879 |
+
function createTickContext(parent, index, tick) {
|
4880 |
+
return createContext(parent, {
|
4881 |
+
tick,
|
4882 |
+
index,
|
4883 |
+
type: 'tick'
|
4884 |
+
});
|
4885 |
+
}
|
4886 |
+
function titleAlign(align, position, reverse) {
|
4887 |
+
let ret = _toLeftRightCenter(align);
|
4888 |
+
if ((reverse && position !== 'right') || (!reverse && position === 'right')) {
|
4889 |
+
ret = reverseAlign(ret);
|
4890 |
+
}
|
4891 |
+
return ret;
|
4892 |
+
}
|
4893 |
+
function titleArgs(scale, offset, position, align) {
|
4894 |
+
const {top, left, bottom, right, chart} = scale;
|
4895 |
+
const {chartArea, scales} = chart;
|
4896 |
+
let rotation = 0;
|
4897 |
+
let maxWidth, titleX, titleY;
|
4898 |
+
const height = bottom - top;
|
4899 |
+
const width = right - left;
|
4900 |
+
if (scale.isHorizontal()) {
|
4901 |
+
titleX = _alignStartEnd(align, left, right);
|
4902 |
+
if (isObject(position)) {
|
4903 |
+
const positionAxisID = Object.keys(position)[0];
|
4904 |
+
const value = position[positionAxisID];
|
4905 |
+
titleY = scales[positionAxisID].getPixelForValue(value) + height - offset;
|
4906 |
+
} else if (position === 'center') {
|
4907 |
+
titleY = (chartArea.bottom + chartArea.top) / 2 + height - offset;
|
4908 |
+
} else {
|
4909 |
+
titleY = offsetFromEdge(scale, position, offset);
|
4910 |
+
}
|
4911 |
+
maxWidth = right - left;
|
4912 |
+
} else {
|
4913 |
+
if (isObject(position)) {
|
4914 |
+
const positionAxisID = Object.keys(position)[0];
|
4915 |
+
const value = position[positionAxisID];
|
4916 |
+
titleX = scales[positionAxisID].getPixelForValue(value) - width + offset;
|
4917 |
+
} else if (position === 'center') {
|
4918 |
+
titleX = (chartArea.left + chartArea.right) / 2 - width + offset;
|
4919 |
+
} else {
|
4920 |
+
titleX = offsetFromEdge(scale, position, offset);
|
4921 |
+
}
|
4922 |
+
titleY = _alignStartEnd(align, bottom, top);
|
4923 |
+
rotation = position === 'left' ? -HALF_PI : HALF_PI;
|
4924 |
+
}
|
4925 |
+
return {titleX, titleY, maxWidth, rotation};
|
4926 |
+
}
|
4927 |
+
class Scale extends Element {
|
4928 |
+
constructor(cfg) {
|
4929 |
+
super();
|
4930 |
+
this.id = cfg.id;
|
4931 |
+
this.type = cfg.type;
|
4932 |
+
this.options = undefined;
|
4933 |
+
this.ctx = cfg.ctx;
|
4934 |
+
this.chart = cfg.chart;
|
4935 |
+
this.top = undefined;
|
4936 |
+
this.bottom = undefined;
|
4937 |
+
this.left = undefined;
|
4938 |
+
this.right = undefined;
|
4939 |
+
this.width = undefined;
|
4940 |
+
this.height = undefined;
|
4941 |
+
this._margins = {
|
4942 |
+
left: 0,
|
4943 |
+
right: 0,
|
4944 |
+
top: 0,
|
4945 |
+
bottom: 0
|
4946 |
+
};
|
4947 |
+
this.maxWidth = undefined;
|
4948 |
+
this.maxHeight = undefined;
|
4949 |
+
this.paddingTop = undefined;
|
4950 |
+
this.paddingBottom = undefined;
|
4951 |
+
this.paddingLeft = undefined;
|
4952 |
+
this.paddingRight = undefined;
|
4953 |
+
this.axis = undefined;
|
4954 |
+
this.labelRotation = undefined;
|
4955 |
+
this.min = undefined;
|
4956 |
+
this.max = undefined;
|
4957 |
+
this._range = undefined;
|
4958 |
+
this.ticks = [];
|
4959 |
+
this._gridLineItems = null;
|
4960 |
+
this._labelItems = null;
|
4961 |
+
this._labelSizes = null;
|
4962 |
+
this._length = 0;
|
4963 |
+
this._maxLength = 0;
|
4964 |
+
this._longestTextCache = {};
|
4965 |
+
this._startPixel = undefined;
|
4966 |
+
this._endPixel = undefined;
|
4967 |
+
this._reversePixels = false;
|
4968 |
+
this._userMax = undefined;
|
4969 |
+
this._userMin = undefined;
|
4970 |
+
this._suggestedMax = undefined;
|
4971 |
+
this._suggestedMin = undefined;
|
4972 |
+
this._ticksLength = 0;
|
4973 |
+
this._borderValue = 0;
|
4974 |
+
this._cache = {};
|
4975 |
+
this._dataLimitsCached = false;
|
4976 |
+
this.$context = undefined;
|
4977 |
+
}
|
4978 |
+
init(options) {
|
4979 |
+
this.options = options.setContext(this.getContext());
|
4980 |
+
this.axis = options.axis;
|
4981 |
+
this._userMin = this.parse(options.min);
|
4982 |
+
this._userMax = this.parse(options.max);
|
4983 |
+
this._suggestedMin = this.parse(options.suggestedMin);
|
4984 |
+
this._suggestedMax = this.parse(options.suggestedMax);
|
4985 |
+
}
|
4986 |
+
parse(raw, index) {
|
4987 |
+
return raw;
|
4988 |
+
}
|
4989 |
+
getUserBounds() {
|
4990 |
+
let {_userMin, _userMax, _suggestedMin, _suggestedMax} = this;
|
4991 |
+
_userMin = finiteOrDefault(_userMin, Number.POSITIVE_INFINITY);
|
4992 |
+
_userMax = finiteOrDefault(_userMax, Number.NEGATIVE_INFINITY);
|
4993 |
+
_suggestedMin = finiteOrDefault(_suggestedMin, Number.POSITIVE_INFINITY);
|
4994 |
+
_suggestedMax = finiteOrDefault(_suggestedMax, Number.NEGATIVE_INFINITY);
|
4995 |
+
return {
|
4996 |
+
min: finiteOrDefault(_userMin, _suggestedMin),
|
4997 |
+
max: finiteOrDefault(_userMax, _suggestedMax),
|
4998 |
+
minDefined: isNumberFinite(_userMin),
|
4999 |
+
maxDefined: isNumberFinite(_userMax)
|
5000 |
+
};
|
5001 |
+
}
|
5002 |
+
getMinMax(canStack) {
|
5003 |
+
let {min, max, minDefined, maxDefined} = this.getUserBounds();
|
5004 |
+
let range;
|
5005 |
+
if (minDefined && maxDefined) {
|
5006 |
+
return {min, max};
|
5007 |
+
}
|
5008 |
+
const metas = this.getMatchingVisibleMetas();
|
5009 |
+
for (let i = 0, ilen = metas.length; i < ilen; ++i) {
|
5010 |
+
range = metas[i].controller.getMinMax(this, canStack);
|
5011 |
+
if (!minDefined) {
|
5012 |
+
min = Math.min(min, range.min);
|
5013 |
+
}
|
5014 |
+
if (!maxDefined) {
|
5015 |
+
max = Math.max(max, range.max);
|
5016 |
+
}
|
5017 |
+
}
|
5018 |
+
min = maxDefined && min > max ? max : min;
|
5019 |
+
max = minDefined && min > max ? min : max;
|
5020 |
+
return {
|
5021 |
+
min: finiteOrDefault(min, finiteOrDefault(max, min)),
|
5022 |
+
max: finiteOrDefault(max, finiteOrDefault(min, max))
|
5023 |
+
};
|
5024 |
+
}
|
5025 |
+
getPadding() {
|
5026 |
+
return {
|
5027 |
+
left: this.paddingLeft || 0,
|
5028 |
+
top: this.paddingTop || 0,
|
5029 |
+
right: this.paddingRight || 0,
|
5030 |
+
bottom: this.paddingBottom || 0
|
5031 |
+
};
|
5032 |
+
}
|
5033 |
+
getTicks() {
|
5034 |
+
return this.ticks;
|
5035 |
+
}
|
5036 |
+
getLabels() {
|
5037 |
+
const data = this.chart.data;
|
5038 |
+
return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || [];
|
5039 |
+
}
|
5040 |
+
beforeLayout() {
|
5041 |
+
this._cache = {};
|
5042 |
+
this._dataLimitsCached = false;
|
5043 |
+
}
|
5044 |
+
beforeUpdate() {
|
5045 |
+
callback(this.options.beforeUpdate, [this]);
|
5046 |
+
}
|
5047 |
+
update(maxWidth, maxHeight, margins) {
|
5048 |
+
const {beginAtZero, grace, ticks: tickOpts} = this.options;
|
5049 |
+
const sampleSize = tickOpts.sampleSize;
|
5050 |
+
this.beforeUpdate();
|
5051 |
+
this.maxWidth = maxWidth;
|
5052 |
+
this.maxHeight = maxHeight;
|
5053 |
+
this._margins = margins = Object.assign({
|
5054 |
+
left: 0,
|
5055 |
+
right: 0,
|
5056 |
+
top: 0,
|
5057 |
+
bottom: 0
|
5058 |
+
}, margins);
|
5059 |
+
this.ticks = null;
|
5060 |
+
this._labelSizes = null;
|
5061 |
+
this._gridLineItems = null;
|
5062 |
+
this._labelItems = null;
|
5063 |
+
this.beforeSetDimensions();
|
5064 |
+
this.setDimensions();
|
5065 |
+
this.afterSetDimensions();
|
5066 |
+
this._maxLength = this.isHorizontal()
|
5067 |
+
? this.width + margins.left + margins.right
|
5068 |
+
: this.height + margins.top + margins.bottom;
|
5069 |
+
if (!this._dataLimitsCached) {
|
5070 |
+
this.beforeDataLimits();
|
5071 |
+
this.determineDataLimits();
|
5072 |
+
this.afterDataLimits();
|
5073 |
+
this._range = _addGrace(this, grace, beginAtZero);
|
5074 |
+
this._dataLimitsCached = true;
|
5075 |
+
}
|
5076 |
+
this.beforeBuildTicks();
|
5077 |
+
this.ticks = this.buildTicks() || [];
|
5078 |
+
this.afterBuildTicks();
|
5079 |
+
const samplingEnabled = sampleSize < this.ticks.length;
|
5080 |
+
this._convertTicksToLabels(samplingEnabled ? sample(this.ticks, sampleSize) : this.ticks);
|
5081 |
+
this.configure();
|
5082 |
+
this.beforeCalculateLabelRotation();
|
5083 |
+
this.calculateLabelRotation();
|
5084 |
+
this.afterCalculateLabelRotation();
|
5085 |
+
if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto')) {
|
5086 |
+
this.ticks = autoSkip(this, this.ticks);
|
5087 |
+
this._labelSizes = null;
|
5088 |
+
}
|
5089 |
+
if (samplingEnabled) {
|
5090 |
+
this._convertTicksToLabels(this.ticks);
|
5091 |
+
}
|
5092 |
+
this.beforeFit();
|
5093 |
+
this.fit();
|
5094 |
+
this.afterFit();
|
5095 |
+
this.afterUpdate();
|
5096 |
+
}
|
5097 |
+
configure() {
|
5098 |
+
let reversePixels = this.options.reverse;
|
5099 |
+
let startPixel, endPixel;
|
5100 |
+
if (this.isHorizontal()) {
|
5101 |
+
startPixel = this.left;
|
5102 |
+
endPixel = this.right;
|
5103 |
+
} else {
|
5104 |
+
startPixel = this.top;
|
5105 |
+
endPixel = this.bottom;
|
5106 |
+
reversePixels = !reversePixels;
|
5107 |
+
}
|
5108 |
+
this._startPixel = startPixel;
|
5109 |
+
this._endPixel = endPixel;
|
5110 |
+
this._reversePixels = reversePixels;
|
5111 |
+
this._length = endPixel - startPixel;
|
5112 |
+
this._alignToPixels = this.options.alignToPixels;
|
5113 |
+
}
|
5114 |
+
afterUpdate() {
|
5115 |
+
callback(this.options.afterUpdate, [this]);
|
5116 |
+
}
|
5117 |
+
beforeSetDimensions() {
|
5118 |
+
callback(this.options.beforeSetDimensions, [this]);
|
5119 |
+
}
|
5120 |
+
setDimensions() {
|
5121 |
+
if (this.isHorizontal()) {
|
5122 |
+
this.width = this.maxWidth;
|
5123 |
+
this.left = 0;
|
5124 |
+
this.right = this.width;
|
5125 |
+
} else {
|
5126 |
+
this.height = this.maxHeight;
|
5127 |
+
this.top = 0;
|
5128 |
+
this.bottom = this.height;
|
5129 |
+
}
|
5130 |
+
this.paddingLeft = 0;
|
5131 |
+
this.paddingTop = 0;
|
5132 |
+
this.paddingRight = 0;
|
5133 |
+
this.paddingBottom = 0;
|
5134 |
+
}
|
5135 |
+
afterSetDimensions() {
|
5136 |
+
callback(this.options.afterSetDimensions, [this]);
|
5137 |
+
}
|
5138 |
+
_callHooks(name) {
|
5139 |
+
this.chart.notifyPlugins(name, this.getContext());
|
5140 |
+
callback(this.options[name], [this]);
|
5141 |
+
}
|
5142 |
+
beforeDataLimits() {
|
5143 |
+
this._callHooks('beforeDataLimits');
|
5144 |
+
}
|
5145 |
+
determineDataLimits() {}
|
5146 |
+
afterDataLimits() {
|
5147 |
+
this._callHooks('afterDataLimits');
|
5148 |
+
}
|
5149 |
+
beforeBuildTicks() {
|
5150 |
+
this._callHooks('beforeBuildTicks');
|
5151 |
+
}
|
5152 |
+
buildTicks() {
|
5153 |
+
return [];
|
5154 |
+
}
|
5155 |
+
afterBuildTicks() {
|
5156 |
+
this._callHooks('afterBuildTicks');
|
5157 |
+
}
|
5158 |
+
beforeTickToLabelConversion() {
|
5159 |
+
callback(this.options.beforeTickToLabelConversion, [this]);
|
5160 |
+
}
|
5161 |
+
generateTickLabels(ticks) {
|
5162 |
+
const tickOpts = this.options.ticks;
|
5163 |
+
let i, ilen, tick;
|
5164 |
+
for (i = 0, ilen = ticks.length; i < ilen; i++) {
|
5165 |
+
tick = ticks[i];
|
5166 |
+
tick.label = callback(tickOpts.callback, [tick.value, i, ticks], this);
|
5167 |
+
}
|
5168 |
+
}
|
5169 |
+
afterTickToLabelConversion() {
|
5170 |
+
callback(this.options.afterTickToLabelConversion, [this]);
|
5171 |
+
}
|
5172 |
+
beforeCalculateLabelRotation() {
|
5173 |
+
callback(this.options.beforeCalculateLabelRotation, [this]);
|
5174 |
+
}
|
5175 |
+
calculateLabelRotation() {
|
5176 |
+
const options = this.options;
|
5177 |
+
const tickOpts = options.ticks;
|
5178 |
+
const numTicks = this.ticks.length;
|
5179 |
+
const minRotation = tickOpts.minRotation || 0;
|
5180 |
+
const maxRotation = tickOpts.maxRotation;
|
5181 |
+
let labelRotation = minRotation;
|
5182 |
+
let tickWidth, maxHeight, maxLabelDiagonal;
|
5183 |
+
if (!this._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !this.isHorizontal()) {
|
5184 |
+
this.labelRotation = minRotation;
|
5185 |
+
return;
|
5186 |
+
}
|
5187 |
+
const labelSizes = this._getLabelSizes();
|
5188 |
+
const maxLabelWidth = labelSizes.widest.width;
|
5189 |
+
const maxLabelHeight = labelSizes.highest.height;
|
5190 |
+
const maxWidth = _limitValue(this.chart.width - maxLabelWidth, 0, this.maxWidth);
|
5191 |
+
tickWidth = options.offset ? this.maxWidth / numTicks : maxWidth / (numTicks - 1);
|
5192 |
+
if (maxLabelWidth + 6 > tickWidth) {
|
5193 |
+
tickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1));
|
5194 |
+
maxHeight = this.maxHeight - getTickMarkLength(options.grid)
|
5195 |
+
- tickOpts.padding - getTitleHeight(options.title, this.chart.options.font);
|
5196 |
+
maxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight);
|
5197 |
+
labelRotation = toDegrees(Math.min(
|
5198 |
+
Math.asin(_limitValue((labelSizes.highest.height + 6) / tickWidth, -1, 1)),
|
5199 |
+
Math.asin(_limitValue(maxHeight / maxLabelDiagonal, -1, 1)) - Math.asin(_limitValue(maxLabelHeight / maxLabelDiagonal, -1, 1))
|
5200 |
+
));
|
5201 |
+
labelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation));
|
5202 |
+
}
|
5203 |
+
this.labelRotation = labelRotation;
|
5204 |
+
}
|
5205 |
+
afterCalculateLabelRotation() {
|
5206 |
+
callback(this.options.afterCalculateLabelRotation, [this]);
|
5207 |
+
}
|
5208 |
+
beforeFit() {
|
5209 |
+
callback(this.options.beforeFit, [this]);
|
5210 |
+
}
|
5211 |
+
fit() {
|
5212 |
+
const minSize = {
|
5213 |
+
width: 0,
|
5214 |
+
height: 0
|
5215 |
+
};
|
5216 |
+
const {chart, options: {ticks: tickOpts, title: titleOpts, grid: gridOpts}} = this;
|
5217 |
+
const display = this._isVisible();
|
5218 |
+
const isHorizontal = this.isHorizontal();
|
5219 |
+
if (display) {
|
5220 |
+
const titleHeight = getTitleHeight(titleOpts, chart.options.font);
|
5221 |
+
if (isHorizontal) {
|
5222 |
+
minSize.width = this.maxWidth;
|
5223 |
+
minSize.height = getTickMarkLength(gridOpts) + titleHeight;
|
5224 |
+
} else {
|
5225 |
+
minSize.height = this.maxHeight;
|
5226 |
+
minSize.width = getTickMarkLength(gridOpts) + titleHeight;
|
5227 |
+
}
|
5228 |
+
if (tickOpts.display && this.ticks.length) {
|
5229 |
+
const {first, last, widest, highest} = this._getLabelSizes();
|
5230 |
+
const tickPadding = tickOpts.padding * 2;
|
5231 |
+
const angleRadians = toRadians(this.labelRotation);
|
5232 |
+
const cos = Math.cos(angleRadians);
|
5233 |
+
const sin = Math.sin(angleRadians);
|
5234 |
+
if (isHorizontal) {
|
5235 |
+
const labelHeight = tickOpts.mirror ? 0 : sin * widest.width + cos * highest.height;
|
5236 |
+
minSize.height = Math.min(this.maxHeight, minSize.height + labelHeight + tickPadding);
|
5237 |
+
} else {
|
5238 |
+
const labelWidth = tickOpts.mirror ? 0 : cos * widest.width + sin * highest.height;
|
5239 |
+
minSize.width = Math.min(this.maxWidth, minSize.width + labelWidth + tickPadding);
|
5240 |
}
|
5241 |
+
this._calculatePadding(first, last, sin, cos);
|
5242 |
+
}
|
5243 |
+
}
|
5244 |
+
this._handleMargins();
|
5245 |
+
if (isHorizontal) {
|
5246 |
+
this.width = this._length = chart.width - this._margins.left - this._margins.right;
|
5247 |
+
this.height = minSize.height;
|
5248 |
+
} else {
|
5249 |
+
this.width = minSize.width;
|
5250 |
+
this.height = this._length = chart.height - this._margins.top - this._margins.bottom;
|
5251 |
+
}
|
5252 |
+
}
|
5253 |
+
_calculatePadding(first, last, sin, cos) {
|
5254 |
+
const {ticks: {align, padding}, position} = this.options;
|
5255 |
+
const isRotated = this.labelRotation !== 0;
|
5256 |
+
const labelsBelowTicks = position !== 'top' && this.axis === 'x';
|
5257 |
+
if (this.isHorizontal()) {
|
5258 |
+
const offsetLeft = this.getPixelForTick(0) - this.left;
|
5259 |
+
const offsetRight = this.right - this.getPixelForTick(this.ticks.length - 1);
|
5260 |
+
let paddingLeft = 0;
|
5261 |
+
let paddingRight = 0;
|
5262 |
+
if (isRotated) {
|
5263 |
+
if (labelsBelowTicks) {
|
5264 |
+
paddingLeft = cos * first.width;
|
5265 |
+
paddingRight = sin * last.height;
|
5266 |
+
} else {
|
5267 |
+
paddingLeft = sin * first.height;
|
5268 |
+
paddingRight = cos * last.width;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5269 |
}
|
5270 |
+
} else if (align === 'start') {
|
5271 |
+
paddingRight = last.width;
|
5272 |
+
} else if (align === 'end') {
|
5273 |
+
paddingLeft = first.width;
|
5274 |
+
} else {
|
5275 |
+
paddingLeft = first.width / 2;
|
5276 |
+
paddingRight = last.width / 2;
|
5277 |
+
}
|
5278 |
+
this.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * this.width / (this.width - offsetLeft), 0);
|
5279 |
+
this.paddingRight = Math.max((paddingRight - offsetRight + padding) * this.width / (this.width - offsetRight), 0);
|
5280 |
+
} else {
|
5281 |
+
let paddingTop = last.height / 2;
|
5282 |
+
let paddingBottom = first.height / 2;
|
5283 |
+
if (align === 'start') {
|
5284 |
+
paddingTop = 0;
|
5285 |
+
paddingBottom = first.height;
|
5286 |
+
} else if (align === 'end') {
|
5287 |
+
paddingTop = last.height;
|
5288 |
+
paddingBottom = 0;
|
5289 |
+
}
|
5290 |
+
this.paddingTop = paddingTop + padding;
|
5291 |
+
this.paddingBottom = paddingBottom + padding;
|
5292 |
+
}
|
5293 |
+
}
|
5294 |
+
_handleMargins() {
|
5295 |
+
if (this._margins) {
|
5296 |
+
this._margins.left = Math.max(this.paddingLeft, this._margins.left);
|
5297 |
+
this._margins.top = Math.max(this.paddingTop, this._margins.top);
|
5298 |
+
this._margins.right = Math.max(this.paddingRight, this._margins.right);
|
5299 |
+
this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom);
|
5300 |
+
}
|
5301 |
+
}
|
5302 |
+
afterFit() {
|
5303 |
+
callback(this.options.afterFit, [this]);
|
5304 |
+
}
|
5305 |
+
isHorizontal() {
|
5306 |
+
const {axis, position} = this.options;
|
5307 |
+
return position === 'top' || position === 'bottom' || axis === 'x';
|
5308 |
+
}
|
5309 |
+
isFullSize() {
|
5310 |
+
return this.options.fullSize;
|
5311 |
+
}
|
5312 |
+
_convertTicksToLabels(ticks) {
|
5313 |
+
this.beforeTickToLabelConversion();
|
5314 |
+
this.generateTickLabels(ticks);
|
5315 |
+
let i, ilen;
|
5316 |
+
for (i = 0, ilen = ticks.length; i < ilen; i++) {
|
5317 |
+
if (isNullOrUndef(ticks[i].label)) {
|
5318 |
+
ticks.splice(i, 1);
|
5319 |
+
ilen--;
|
5320 |
+
i--;
|
5321 |
+
}
|
5322 |
+
}
|
5323 |
+
this.afterTickToLabelConversion();
|
5324 |
+
}
|
5325 |
+
_getLabelSizes() {
|
5326 |
+
let labelSizes = this._labelSizes;
|
5327 |
+
if (!labelSizes) {
|
5328 |
+
const sampleSize = this.options.ticks.sampleSize;
|
5329 |
+
let ticks = this.ticks;
|
5330 |
+
if (sampleSize < ticks.length) {
|
5331 |
+
ticks = sample(ticks, sampleSize);
|
5332 |
+
}
|
5333 |
+
this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length);
|
5334 |
+
}
|
5335 |
+
return labelSizes;
|
5336 |
+
}
|
5337 |
+
_computeLabelSizes(ticks, length) {
|
5338 |
+
const {ctx, _longestTextCache: caches} = this;
|
5339 |
+
const widths = [];
|
5340 |
+
const heights = [];
|
5341 |
+
let widestLabelSize = 0;
|
5342 |
+
let highestLabelSize = 0;
|
5343 |
+
let i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel;
|
5344 |
+
for (i = 0; i < length; ++i) {
|
5345 |
+
label = ticks[i].label;
|
5346 |
+
tickFont = this._resolveTickFontOptions(i);
|
5347 |
+
ctx.font = fontString = tickFont.string;
|
5348 |
+
cache = caches[fontString] = caches[fontString] || {data: {}, gc: []};
|
5349 |
+
lineHeight = tickFont.lineHeight;
|
5350 |
+
width = height = 0;
|
5351 |
+
if (!isNullOrUndef(label) && !isArray(label)) {
|
5352 |
+
width = _measureText(ctx, cache.data, cache.gc, width, label);
|
5353 |
+
height = lineHeight;
|
5354 |
+
} else if (isArray(label)) {
|
5355 |
+
for (j = 0, jlen = label.length; j < jlen; ++j) {
|
5356 |
+
nestedLabel = label[j];
|
5357 |
+
if (!isNullOrUndef(nestedLabel) && !isArray(nestedLabel)) {
|
5358 |
+
width = _measureText(ctx, cache.data, cache.gc, width, nestedLabel);
|
5359 |
+
height += lineHeight;
|
5360 |
+
}
|
5361 |
}
|
5362 |
+
}
|
5363 |
+
widths.push(width);
|
5364 |
+
heights.push(height);
|
5365 |
+
widestLabelSize = Math.max(width, widestLabelSize);
|
5366 |
+
highestLabelSize = Math.max(height, highestLabelSize);
|
5367 |
+
}
|
5368 |
+
garbageCollect(caches, length);
|
5369 |
+
const widest = widths.indexOf(widestLabelSize);
|
5370 |
+
const highest = heights.indexOf(highestLabelSize);
|
5371 |
+
const valueAt = (idx) => ({width: widths[idx] || 0, height: heights[idx] || 0});
|
5372 |
+
return {
|
5373 |
+
first: valueAt(0),
|
5374 |
+
last: valueAt(length - 1),
|
5375 |
+
widest: valueAt(widest),
|
5376 |
+
highest: valueAt(highest),
|
5377 |
+
widths,
|
5378 |
+
heights,
|
5379 |
+
};
|
5380 |
+
}
|
5381 |
+
getLabelForValue(value) {
|
5382 |
+
return value;
|
5383 |
+
}
|
5384 |
+
getPixelForValue(value, index) {
|
5385 |
+
return NaN;
|
5386 |
+
}
|
5387 |
+
getValueForPixel(pixel) {}
|
5388 |
+
getPixelForTick(index) {
|
5389 |
+
const ticks = this.ticks;
|
5390 |
+
if (index < 0 || index > ticks.length - 1) {
|
5391 |
+
return null;
|
5392 |
+
}
|
5393 |
+
return this.getPixelForValue(ticks[index].value);
|
5394 |
+
}
|
5395 |
+
getPixelForDecimal(decimal) {
|
5396 |
+
if (this._reversePixels) {
|
5397 |
+
decimal = 1 - decimal;
|
5398 |
+
}
|
5399 |
+
const pixel = this._startPixel + decimal * this._length;
|
5400 |
+
return _int16Range(this._alignToPixels ? _alignPixel(this.chart, pixel, 0) : pixel);
|
5401 |
+
}
|
5402 |
+
getDecimalForPixel(pixel) {
|
5403 |
+
const decimal = (pixel - this._startPixel) / this._length;
|
5404 |
+
return this._reversePixels ? 1 - decimal : decimal;
|
5405 |
+
}
|
5406 |
+
getBasePixel() {
|
5407 |
+
return this.getPixelForValue(this.getBaseValue());
|
5408 |
+
}
|
5409 |
+
getBaseValue() {
|
5410 |
+
const {min, max} = this;
|
5411 |
+
return min < 0 && max < 0 ? max :
|
5412 |
+
min > 0 && max > 0 ? min :
|
5413 |
+
0;
|
5414 |
+
}
|
5415 |
+
getContext(index) {
|
5416 |
+
const ticks = this.ticks || [];
|
5417 |
+
if (index >= 0 && index < ticks.length) {
|
5418 |
+
const tick = ticks[index];
|
5419 |
+
return tick.$context ||
|
5420 |
+
(tick.$context = createTickContext(this.getContext(), index, tick));
|
5421 |
+
}
|
5422 |
+
return this.$context ||
|
5423 |
+
(this.$context = createScaleContext(this.chart.getContext(), this));
|
5424 |
+
}
|
5425 |
+
_tickSize() {
|
5426 |
+
const optionTicks = this.options.ticks;
|
5427 |
+
const rot = toRadians(this.labelRotation);
|
5428 |
+
const cos = Math.abs(Math.cos(rot));
|
5429 |
+
const sin = Math.abs(Math.sin(rot));
|
5430 |
+
const labelSizes = this._getLabelSizes();
|
5431 |
+
const padding = optionTicks.autoSkipPadding || 0;
|
5432 |
+
const w = labelSizes ? labelSizes.widest.width + padding : 0;
|
5433 |
+
const h = labelSizes ? labelSizes.highest.height + padding : 0;
|
5434 |
+
return this.isHorizontal()
|
5435 |
+
? h * cos > w * sin ? w / cos : h / sin
|
5436 |
+
: h * sin < w * cos ? h / cos : w / sin;
|
5437 |
+
}
|
5438 |
+
_isVisible() {
|
5439 |
+
const display = this.options.display;
|
5440 |
+
if (display !== 'auto') {
|
5441 |
+
return !!display;
|
5442 |
+
}
|
5443 |
+
return this.getMatchingVisibleMetas().length > 0;
|
5444 |
+
}
|
5445 |
+
_computeGridLineItems(chartArea) {
|
5446 |
+
const axis = this.axis;
|
5447 |
+
const chart = this.chart;
|
5448 |
+
const options = this.options;
|
5449 |
+
const {grid, position} = options;
|
5450 |
+
const offset = grid.offset;
|
5451 |
+
const isHorizontal = this.isHorizontal();
|
5452 |
+
const ticks = this.ticks;
|
5453 |
+
const ticksLength = ticks.length + (offset ? 1 : 0);
|
5454 |
+
const tl = getTickMarkLength(grid);
|
5455 |
+
const items = [];
|
5456 |
+
const borderOpts = grid.setContext(this.getContext());
|
5457 |
+
const axisWidth = borderOpts.drawBorder ? borderOpts.borderWidth : 0;
|
5458 |
+
const axisHalfWidth = axisWidth / 2;
|
5459 |
+
const alignBorderValue = function(pixel) {
|
5460 |
+
return _alignPixel(chart, pixel, axisWidth);
|
5461 |
+
};
|
5462 |
+
let borderValue, i, lineValue, alignedLineValue;
|
5463 |
+
let tx1, ty1, tx2, ty2, x1, y1, x2, y2;
|
5464 |
+
if (position === 'top') {
|
5465 |
+
borderValue = alignBorderValue(this.bottom);
|
5466 |
+
ty1 = this.bottom - tl;
|
5467 |
+
ty2 = borderValue - axisHalfWidth;
|
5468 |
+
y1 = alignBorderValue(chartArea.top) + axisHalfWidth;
|
5469 |
+
y2 = chartArea.bottom;
|
5470 |
+
} else if (position === 'bottom') {
|
5471 |
+
borderValue = alignBorderValue(this.top);
|
5472 |
+
y1 = chartArea.top;
|
5473 |
+
y2 = alignBorderValue(chartArea.bottom) - axisHalfWidth;
|
5474 |
+
ty1 = borderValue + axisHalfWidth;
|
5475 |
+
ty2 = this.top + tl;
|
5476 |
+
} else if (position === 'left') {
|
5477 |
+
borderValue = alignBorderValue(this.right);
|
5478 |
+
tx1 = this.right - tl;
|
5479 |
+
tx2 = borderValue - axisHalfWidth;
|
5480 |
+
x1 = alignBorderValue(chartArea.left) + axisHalfWidth;
|
5481 |
+
x2 = chartArea.right;
|
5482 |
+
} else if (position === 'right') {
|
5483 |
+
borderValue = alignBorderValue(this.left);
|
5484 |
+
x1 = chartArea.left;
|
5485 |
+
x2 = alignBorderValue(chartArea.right) - axisHalfWidth;
|
5486 |
+
tx1 = borderValue + axisHalfWidth;
|
5487 |
+
tx2 = this.left + tl;
|
5488 |
+
} else if (axis === 'x') {
|
5489 |
+
if (position === 'center') {
|
5490 |
+
borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2 + 0.5);
|
5491 |
+
} else if (isObject(position)) {
|
5492 |
+
const positionAxisID = Object.keys(position)[0];
|
5493 |
+
const value = position[positionAxisID];
|
5494 |
+
borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));
|
5495 |
+
}
|
5496 |
+
y1 = chartArea.top;
|
5497 |
+
y2 = chartArea.bottom;
|
5498 |
+
ty1 = borderValue + axisHalfWidth;
|
5499 |
+
ty2 = ty1 + tl;
|
5500 |
+
} else if (axis === 'y') {
|
5501 |
+
if (position === 'center') {
|
5502 |
+
borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2);
|
5503 |
+
} else if (isObject(position)) {
|
5504 |
+
const positionAxisID = Object.keys(position)[0];
|
5505 |
+
const value = position[positionAxisID];
|
5506 |
+
borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));
|
5507 |
+
}
|
5508 |
+
tx1 = borderValue - axisHalfWidth;
|
5509 |
+
tx2 = tx1 - tl;
|
5510 |
+
x1 = chartArea.left;
|
5511 |
+
x2 = chartArea.right;
|
5512 |
+
}
|
5513 |
+
const limit = valueOrDefault(options.ticks.maxTicksLimit, ticksLength);
|
5514 |
+
const step = Math.max(1, Math.ceil(ticksLength / limit));
|
5515 |
+
for (i = 0; i < ticksLength; i += step) {
|
5516 |
+
const optsAtIndex = grid.setContext(this.getContext(i));
|
5517 |
+
const lineWidth = optsAtIndex.lineWidth;
|
5518 |
+
const lineColor = optsAtIndex.color;
|
5519 |
+
const borderDash = grid.borderDash || [];
|
5520 |
+
const borderDashOffset = optsAtIndex.borderDashOffset;
|
5521 |
+
const tickWidth = optsAtIndex.tickWidth;
|
5522 |
+
const tickColor = optsAtIndex.tickColor;
|
5523 |
+
const tickBorderDash = optsAtIndex.tickBorderDash || [];
|
5524 |
+
const tickBorderDashOffset = optsAtIndex.tickBorderDashOffset;
|
5525 |
+
lineValue = getPixelForGridLine(this, i, offset);
|
5526 |
+
if (lineValue === undefined) {
|
5527 |
+
continue;
|
5528 |
+
}
|
5529 |
+
alignedLineValue = _alignPixel(chart, lineValue, lineWidth);
|
5530 |
+
if (isHorizontal) {
|
5531 |
+
tx1 = tx2 = x1 = x2 = alignedLineValue;
|
5532 |
+
} else {
|
5533 |
+
ty1 = ty2 = y1 = y2 = alignedLineValue;
|
5534 |
+
}
|
5535 |
+
items.push({
|
5536 |
+
tx1,
|
5537 |
+
ty1,
|
5538 |
+
tx2,
|
5539 |
+
ty2,
|
5540 |
+
x1,
|
5541 |
+
y1,
|
5542 |
+
x2,
|
5543 |
+
y2,
|
5544 |
+
width: lineWidth,
|
5545 |
+
color: lineColor,
|
5546 |
+
borderDash,
|
5547 |
+
borderDashOffset,
|
5548 |
+
tickWidth,
|
5549 |
+
tickColor,
|
5550 |
+
tickBorderDash,
|
5551 |
+
tickBorderDashOffset,
|
5552 |
+
});
|
5553 |
+
}
|
5554 |
+
this._ticksLength = ticksLength;
|
5555 |
+
this._borderValue = borderValue;
|
5556 |
+
return items;
|
5557 |
+
}
|
5558 |
+
_computeLabelItems(chartArea) {
|
5559 |
+
const axis = this.axis;
|
5560 |
+
const options = this.options;
|
5561 |
+
const {position, ticks: optionTicks} = options;
|
5562 |
+
const isHorizontal = this.isHorizontal();
|
5563 |
+
const ticks = this.ticks;
|
5564 |
+
const {align, crossAlign, padding, mirror} = optionTicks;
|
5565 |
+
const tl = getTickMarkLength(options.grid);
|
5566 |
+
const tickAndPadding = tl + padding;
|
5567 |
+
const hTickAndPadding = mirror ? -padding : tickAndPadding;
|
5568 |
+
const rotation = -toRadians(this.labelRotation);
|
5569 |
+
const items = [];
|
5570 |
+
let i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset;
|
5571 |
+
let textBaseline = 'middle';
|
5572 |
+
if (position === 'top') {
|
5573 |
+
y = this.bottom - hTickAndPadding;
|
5574 |
+
textAlign = this._getXAxisLabelAlignment();
|
5575 |
+
} else if (position === 'bottom') {
|
5576 |
+
y = this.top + hTickAndPadding;
|
5577 |
+
textAlign = this._getXAxisLabelAlignment();
|
5578 |
+
} else if (position === 'left') {
|
5579 |
+
const ret = this._getYAxisLabelAlignment(tl);
|
5580 |
+
textAlign = ret.textAlign;
|
5581 |
+
x = ret.x;
|
5582 |
+
} else if (position === 'right') {
|
5583 |
+
const ret = this._getYAxisLabelAlignment(tl);
|
5584 |
+
textAlign = ret.textAlign;
|
5585 |
+
x = ret.x;
|
5586 |
+
} else if (axis === 'x') {
|
5587 |
+
if (position === 'center') {
|
5588 |
+
y = ((chartArea.top + chartArea.bottom) / 2) + tickAndPadding;
|
5589 |
+
} else if (isObject(position)) {
|
5590 |
+
const positionAxisID = Object.keys(position)[0];
|
5591 |
+
const value = position[positionAxisID];
|
5592 |
+
y = this.chart.scales[positionAxisID].getPixelForValue(value) + tickAndPadding;
|
5593 |
+
}
|
5594 |
+
textAlign = this._getXAxisLabelAlignment();
|
5595 |
+
} else if (axis === 'y') {
|
5596 |
+
if (position === 'center') {
|
5597 |
+
x = ((chartArea.left + chartArea.right) / 2) - tickAndPadding;
|
5598 |
+
} else if (isObject(position)) {
|
5599 |
+
const positionAxisID = Object.keys(position)[0];
|
5600 |
+
const value = position[positionAxisID];
|
5601 |
+
x = this.chart.scales[positionAxisID].getPixelForValue(value);
|
5602 |
+
}
|
5603 |
+
textAlign = this._getYAxisLabelAlignment(tl).textAlign;
|
5604 |
+
}
|
5605 |
+
if (axis === 'y') {
|
5606 |
+
if (align === 'start') {
|
5607 |
+
textBaseline = 'top';
|
5608 |
+
} else if (align === 'end') {
|
5609 |
+
textBaseline = 'bottom';
|
5610 |
+
}
|
5611 |
+
}
|
5612 |
+
const labelSizes = this._getLabelSizes();
|
5613 |
+
for (i = 0, ilen = ticks.length; i < ilen; ++i) {
|
5614 |
+
tick = ticks[i];
|
5615 |
+
label = tick.label;
|
5616 |
+
const optsAtIndex = optionTicks.setContext(this.getContext(i));
|
5617 |
+
pixel = this.getPixelForTick(i) + optionTicks.labelOffset;
|
5618 |
+
font = this._resolveTickFontOptions(i);
|
5619 |
+
lineHeight = font.lineHeight;
|
5620 |
+
lineCount = isArray(label) ? label.length : 1;
|
5621 |
+
const halfCount = lineCount / 2;
|
5622 |
+
const color = optsAtIndex.color;
|
5623 |
+
const strokeColor = optsAtIndex.textStrokeColor;
|
5624 |
+
const strokeWidth = optsAtIndex.textStrokeWidth;
|
5625 |
+
if (isHorizontal) {
|
5626 |
+
x = pixel;
|
5627 |
+
if (position === 'top') {
|
5628 |
+
if (crossAlign === 'near' || rotation !== 0) {
|
5629 |
+
textOffset = -lineCount * lineHeight + lineHeight / 2;
|
5630 |
+
} else if (crossAlign === 'center') {
|
5631 |
+
textOffset = -labelSizes.highest.height / 2 - halfCount * lineHeight + lineHeight;
|
5632 |
+
} else {
|
5633 |
+
textOffset = -labelSizes.highest.height + lineHeight / 2;
|
5634 |
+
}
|
5635 |
+
} else {
|
5636 |
+
if (crossAlign === 'near' || rotation !== 0) {
|
5637 |
+
textOffset = lineHeight / 2;
|
5638 |
+
} else if (crossAlign === 'center') {
|
5639 |
+
textOffset = labelSizes.highest.height / 2 - halfCount * lineHeight;
|
5640 |
+
} else {
|
5641 |
+
textOffset = labelSizes.highest.height - lineCount * lineHeight;
|
5642 |
+
}
|
5643 |
}
|
5644 |
+
if (mirror) {
|
5645 |
+
textOffset *= -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5646 |
}
|
5647 |
+
} else {
|
5648 |
+
y = pixel;
|
5649 |
+
textOffset = (1 - lineCount) * lineHeight / 2;
|
5650 |
+
}
|
5651 |
+
let backdrop;
|
5652 |
+
if (optsAtIndex.showLabelBackdrop) {
|
5653 |
+
const labelPadding = toPadding(optsAtIndex.backdropPadding);
|
5654 |
+
const height = labelSizes.heights[i];
|
5655 |
+
const width = labelSizes.widths[i];
|
5656 |
+
let top = y + textOffset - labelPadding.top;
|
5657 |
+
let left = x - labelPadding.left;
|
5658 |
+
switch (textBaseline) {
|
5659 |
+
case 'middle':
|
5660 |
+
top -= height / 2;
|
5661 |
+
break;
|
5662 |
+
case 'bottom':
|
5663 |
+
top -= height;
|
5664 |
+
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5665 |
}
|
5666 |
+
switch (textAlign) {
|
5667 |
+
case 'center':
|
5668 |
+
left -= width / 2;
|
5669 |
+
break;
|
5670 |
+
case 'right':
|
5671 |
+
left -= width;
|
5672 |
+
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5673 |
}
|
5674 |
+
backdrop = {
|
5675 |
+
left,
|
5676 |
+
top,
|
5677 |
+
width: width + labelPadding.width,
|
5678 |
+
height: height + labelPadding.height,
|
5679 |
+
color: optsAtIndex.backdropColor,
|
5680 |
+
};
|
5681 |
+
}
|
5682 |
+
items.push({
|
5683 |
+
rotation,
|
5684 |
+
label,
|
5685 |
+
font,
|
5686 |
+
color,
|
5687 |
+
strokeColor,
|
5688 |
+
strokeWidth,
|
5689 |
+
textOffset,
|
5690 |
+
textAlign,
|
5691 |
+
textBaseline,
|
5692 |
+
translation: [x, y],
|
5693 |
+
backdrop,
|
5694 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5695 |
}
|
5696 |
+
return items;
|
5697 |
+
}
|
5698 |
+
_getXAxisLabelAlignment() {
|
5699 |
+
const {position, ticks} = this.options;
|
5700 |
+
const rotation = -toRadians(this.labelRotation);
|
5701 |
+
if (rotation) {
|
5702 |
+
return position === 'top' ? 'left' : 'right';
|
5703 |
+
}
|
5704 |
+
let align = 'center';
|
5705 |
+
if (ticks.align === 'start') {
|
5706 |
+
align = 'left';
|
5707 |
+
} else if (ticks.align === 'end') {
|
5708 |
+
align = 'right';
|
5709 |
+
}
|
5710 |
+
return align;
|
5711 |
+
}
|
5712 |
+
_getYAxisLabelAlignment(tl) {
|
5713 |
+
const {position, ticks: {crossAlign, mirror, padding}} = this.options;
|
5714 |
+
const labelSizes = this._getLabelSizes();
|
5715 |
+
const tickAndPadding = tl + padding;
|
5716 |
+
const widest = labelSizes.widest.width;
|
5717 |
+
let textAlign;
|
5718 |
+
let x;
|
5719 |
+
if (position === 'left') {
|
5720 |
+
if (mirror) {
|
5721 |
+
x = this.right + padding;
|
5722 |
+
if (crossAlign === 'near') {
|
5723 |
+
textAlign = 'left';
|
5724 |
+
} else if (crossAlign === 'center') {
|
5725 |
+
textAlign = 'center';
|
5726 |
+
x += (widest / 2);
|
5727 |
+
} else {
|
5728 |
+
textAlign = 'right';
|
5729 |
+
x += widest;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5730 |
}
|
5731 |
+
} else {
|
5732 |
+
x = this.right - tickAndPadding;
|
5733 |
+
if (crossAlign === 'near') {
|
5734 |
+
textAlign = 'right';
|
5735 |
+
} else if (crossAlign === 'center') {
|
5736 |
+
textAlign = 'center';
|
5737 |
+
x -= (widest / 2);
|
5738 |
+
} else {
|
5739 |
+
textAlign = 'left';
|
5740 |
+
x = this.left;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5741 |
}
|
5742 |
+
}
|
5743 |
+
} else if (position === 'right') {
|
5744 |
+
if (mirror) {
|
5745 |
+
x = this.left + padding;
|
5746 |
+
if (crossAlign === 'near') {
|
5747 |
+
textAlign = 'right';
|
5748 |
+
} else if (crossAlign === 'center') {
|
5749 |
+
textAlign = 'center';
|
5750 |
+
x -= (widest / 2);
|
5751 |
+
} else {
|
5752 |
+
textAlign = 'left';
|
5753 |
+
x -= widest;
|
5754 |
}
|
5755 |
+
} else {
|
5756 |
+
x = this.left + tickAndPadding;
|
5757 |
+
if (crossAlign === 'near') {
|
5758 |
+
textAlign = 'left';
|
5759 |
+
} else if (crossAlign === 'center') {
|
5760 |
+
textAlign = 'center';
|
5761 |
+
x += widest / 2;
|
5762 |
+
} else {
|
5763 |
+
textAlign = 'right';
|
5764 |
+
x = this.right;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5765 |
}
|
5766 |
+
}
|
5767 |
+
} else {
|
5768 |
+
textAlign = 'right';
|
5769 |
+
}
|
5770 |
+
return {textAlign, x};
|
5771 |
+
}
|
5772 |
+
_computeLabelArea() {
|
5773 |
+
if (this.options.ticks.mirror) {
|
5774 |
+
return;
|
5775 |
+
}
|
5776 |
+
const chart = this.chart;
|
5777 |
+
const position = this.options.position;
|
5778 |
+
if (position === 'left' || position === 'right') {
|
5779 |
+
return {top: 0, left: this.left, bottom: chart.height, right: this.right};
|
5780 |
+
} if (position === 'top' || position === 'bottom') {
|
5781 |
+
return {top: this.top, left: 0, bottom: this.bottom, right: chart.width};
|
5782 |
+
}
|
5783 |
+
}
|
5784 |
+
drawBackground() {
|
5785 |
+
const {ctx, options: {backgroundColor}, left, top, width, height} = this;
|
5786 |
+
if (backgroundColor) {
|
5787 |
+
ctx.save();
|
5788 |
+
ctx.fillStyle = backgroundColor;
|
5789 |
+
ctx.fillRect(left, top, width, height);
|
5790 |
+
ctx.restore();
|
5791 |
+
}
|
5792 |
+
}
|
5793 |
+
getLineWidthForValue(value) {
|
5794 |
+
const grid = this.options.grid;
|
5795 |
+
if (!this._isVisible() || !grid.display) {
|
5796 |
+
return 0;
|
5797 |
+
}
|
5798 |
+
const ticks = this.ticks;
|
5799 |
+
const index = ticks.findIndex(t => t.value === value);
|
5800 |
+
if (index >= 0) {
|
5801 |
+
const opts = grid.setContext(this.getContext(index));
|
5802 |
+
return opts.lineWidth;
|
5803 |
+
}
|
5804 |
+
return 0;
|
5805 |
+
}
|
5806 |
+
drawGrid(chartArea) {
|
5807 |
+
const grid = this.options.grid;
|
5808 |
+
const ctx = this.ctx;
|
5809 |
+
const items = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(chartArea));
|
5810 |
+
let i, ilen;
|
5811 |
+
const drawLine = (p1, p2, style) => {
|
5812 |
+
if (!style.width || !style.color) {
|
5813 |
+
return;
|
5814 |
+
}
|
5815 |
+
ctx.save();
|
5816 |
+
ctx.lineWidth = style.width;
|
5817 |
+
ctx.strokeStyle = style.color;
|
5818 |
+
ctx.setLineDash(style.borderDash || []);
|
5819 |
+
ctx.lineDashOffset = style.borderDashOffset;
|
5820 |
+
ctx.beginPath();
|
5821 |
+
ctx.moveTo(p1.x, p1.y);
|
5822 |
+
ctx.lineTo(p2.x, p2.y);
|
5823 |
+
ctx.stroke();
|
5824 |
+
ctx.restore();
|
5825 |
+
};
|
5826 |
+
if (grid.display) {
|
5827 |
+
for (i = 0, ilen = items.length; i < ilen; ++i) {
|
5828 |
+
const item = items[i];
|
5829 |
+
if (grid.drawOnChartArea) {
|
5830 |
+
drawLine(
|
5831 |
+
{x: item.x1, y: item.y1},
|
5832 |
+
{x: item.x2, y: item.y2},
|
5833 |
+
item
|
5834 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5835 |
}
|
5836 |
+
if (grid.drawTicks) {
|
5837 |
+
drawLine(
|
5838 |
+
{x: item.tx1, y: item.ty1},
|
5839 |
+
{x: item.tx2, y: item.ty2},
|
5840 |
+
{
|
5841 |
+
color: item.tickColor,
|
5842 |
+
width: item.tickWidth,
|
5843 |
+
borderDash: item.tickBorderDash,
|
5844 |
+
borderDashOffset: item.tickBorderDashOffset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5845 |
}
|
5846 |
+
);
|
5847 |
+
}
|
5848 |
+
}
|
5849 |
+
}
|
5850 |
+
}
|
5851 |
+
drawBorder() {
|
5852 |
+
const {chart, ctx, options: {grid}} = this;
|
5853 |
+
const borderOpts = grid.setContext(this.getContext());
|
5854 |
+
const axisWidth = grid.drawBorder ? borderOpts.borderWidth : 0;
|
5855 |
+
if (!axisWidth) {
|
5856 |
+
return;
|
5857 |
+
}
|
5858 |
+
const lastLineWidth = grid.setContext(this.getContext(0)).lineWidth;
|
5859 |
+
const borderValue = this._borderValue;
|
5860 |
+
let x1, x2, y1, y2;
|
5861 |
+
if (this.isHorizontal()) {
|
5862 |
+
x1 = _alignPixel(chart, this.left, axisWidth) - axisWidth / 2;
|
5863 |
+
x2 = _alignPixel(chart, this.right, lastLineWidth) + lastLineWidth / 2;
|
5864 |
+
y1 = y2 = borderValue;
|
5865 |
+
} else {
|
5866 |
+
y1 = _alignPixel(chart, this.top, axisWidth) - axisWidth / 2;
|
5867 |
+
y2 = _alignPixel(chart, this.bottom, lastLineWidth) + lastLineWidth / 2;
|
5868 |
+
x1 = x2 = borderValue;
|
5869 |
+
}
|
5870 |
+
ctx.save();
|
5871 |
+
ctx.lineWidth = borderOpts.borderWidth;
|
5872 |
+
ctx.strokeStyle = borderOpts.borderColor;
|
5873 |
+
ctx.beginPath();
|
5874 |
+
ctx.moveTo(x1, y1);
|
5875 |
+
ctx.lineTo(x2, y2);
|
5876 |
+
ctx.stroke();
|
5877 |
+
ctx.restore();
|
5878 |
+
}
|
5879 |
+
drawLabels(chartArea) {
|
5880 |
+
const optionTicks = this.options.ticks;
|
5881 |
+
if (!optionTicks.display) {
|
5882 |
+
return;
|
5883 |
+
}
|
5884 |
+
const ctx = this.ctx;
|
5885 |
+
const area = this._computeLabelArea();
|
5886 |
+
if (area) {
|
5887 |
+
clipArea(ctx, area);
|
5888 |
+
}
|
5889 |
+
const items = this._labelItems || (this._labelItems = this._computeLabelItems(chartArea));
|
5890 |
+
let i, ilen;
|
5891 |
+
for (i = 0, ilen = items.length; i < ilen; ++i) {
|
5892 |
+
const item = items[i];
|
5893 |
+
const tickFont = item.font;
|
5894 |
+
const label = item.label;
|
5895 |
+
if (item.backdrop) {
|
5896 |
+
ctx.fillStyle = item.backdrop.color;
|
5897 |
+
ctx.fillRect(item.backdrop.left, item.backdrop.top, item.backdrop.width, item.backdrop.height);
|
5898 |
+
}
|
5899 |
+
let y = item.textOffset;
|
5900 |
+
renderText(ctx, label, 0, y, tickFont, item);
|
5901 |
+
}
|
5902 |
+
if (area) {
|
5903 |
+
unclipArea(ctx);
|
5904 |
+
}
|
5905 |
+
}
|
5906 |
+
drawTitle() {
|
5907 |
+
const {ctx, options: {position, title, reverse}} = this;
|
5908 |
+
if (!title.display) {
|
5909 |
+
return;
|
5910 |
+
}
|
5911 |
+
const font = toFont(title.font);
|
5912 |
+
const padding = toPadding(title.padding);
|
5913 |
+
const align = title.align;
|
5914 |
+
let offset = font.lineHeight / 2;
|
5915 |
+
if (position === 'bottom' || position === 'center' || isObject(position)) {
|
5916 |
+
offset += padding.bottom;
|
5917 |
+
if (isArray(title.text)) {
|
5918 |
+
offset += font.lineHeight * (title.text.length - 1);
|
5919 |
+
}
|
5920 |
+
} else {
|
5921 |
+
offset += padding.top;
|
5922 |
+
}
|
5923 |
+
const {titleX, titleY, maxWidth, rotation} = titleArgs(this, offset, position, align);
|
5924 |
+
renderText(ctx, title.text, 0, 0, font, {
|
5925 |
+
color: title.color,
|
5926 |
+
maxWidth,
|
5927 |
+
rotation,
|
5928 |
+
textAlign: titleAlign(align, position, reverse),
|
5929 |
+
textBaseline: 'middle',
|
5930 |
+
translation: [titleX, titleY],
|
5931 |
+
});
|
5932 |
+
}
|
5933 |
+
draw(chartArea) {
|
5934 |
+
if (!this._isVisible()) {
|
5935 |
+
return;
|
5936 |
+
}
|
5937 |
+
this.drawBackground();
|
5938 |
+
this.drawGrid(chartArea);
|
5939 |
+
this.drawBorder();
|
5940 |
+
this.drawTitle();
|
5941 |
+
this.drawLabels(chartArea);
|
5942 |
+
}
|
5943 |
+
_layers() {
|
5944 |
+
const opts = this.options;
|
5945 |
+
const tz = opts.ticks && opts.ticks.z || 0;
|
5946 |
+
const gz = valueOrDefault(opts.grid && opts.grid.z, -1);
|
5947 |
+
if (!this._isVisible() || this.draw !== Scale.prototype.draw) {
|
5948 |
+
return [{
|
5949 |
+
z: tz,
|
5950 |
+
draw: (chartArea) => {
|
5951 |
+
this.draw(chartArea);
|
5952 |
}
|
5953 |
+
}];
|
5954 |
+
}
|
5955 |
+
return [{
|
5956 |
+
z: gz,
|
5957 |
+
draw: (chartArea) => {
|
5958 |
+
this.drawBackground();
|
5959 |
+
this.drawGrid(chartArea);
|
5960 |
+
this.drawTitle();
|
5961 |
+
}
|
5962 |
+
}, {
|
5963 |
+
z: gz + 1,
|
5964 |
+
draw: () => {
|
5965 |
+
this.drawBorder();
|
5966 |
+
}
|
5967 |
+
}, {
|
5968 |
+
z: tz,
|
5969 |
+
draw: (chartArea) => {
|
5970 |
+
this.drawLabels(chartArea);
|
5971 |
+
}
|
5972 |
+
}];
|
5973 |
+
}
|
5974 |
+
getMatchingVisibleMetas(type) {
|
5975 |
+
const metas = this.chart.getSortedVisibleDatasetMetas();
|
5976 |
+
const axisID = this.axis + 'AxisID';
|
5977 |
+
const result = [];
|
5978 |
+
let i, ilen;
|
5979 |
+
for (i = 0, ilen = metas.length; i < ilen; ++i) {
|
5980 |
+
const meta = metas[i];
|
5981 |
+
if (meta[axisID] === this.id && (!type || meta.type === type)) {
|
5982 |
+
result.push(meta);
|
5983 |
+
}
|
5984 |
+
}
|
5985 |
+
return result;
|
5986 |
+
}
|
5987 |
+
_resolveTickFontOptions(index) {
|
5988 |
+
const opts = this.options.ticks.setContext(this.getContext(index));
|
5989 |
+
return toFont(opts.font);
|
5990 |
+
}
|
5991 |
+
_maxDigits() {
|
5992 |
+
const fontSize = this._resolveTickFontOptions(0).lineHeight;
|
5993 |
+
return (this.isHorizontal() ? this.width : this.height) / fontSize;
|
5994 |
+
}
|
5995 |
+
}
|
5996 |
+
|
5997 |
+
class TypedRegistry {
|
5998 |
+
constructor(type, scope, override) {
|
5999 |
+
this.type = type;
|
6000 |
+
this.scope = scope;
|
6001 |
+
this.override = override;
|
6002 |
+
this.items = Object.create(null);
|
6003 |
+
}
|
6004 |
+
isForType(type) {
|
6005 |
+
return Object.prototype.isPrototypeOf.call(this.type.prototype, type.prototype);
|
6006 |
+
}
|
6007 |
+
register(item) {
|
6008 |
+
const proto = Object.getPrototypeOf(item);
|
6009 |
+
let parentScope;
|
6010 |
+
if (isIChartComponent(proto)) {
|
6011 |
+
parentScope = this.register(proto);
|
6012 |
+
}
|
6013 |
+
const items = this.items;
|
6014 |
+
const id = item.id;
|
6015 |
+
const scope = this.scope + '.' + id;
|
6016 |
+
if (!id) {
|
6017 |
+
throw new Error('class does not have id: ' + item);
|
6018 |
+
}
|
6019 |
+
if (id in items) {
|
6020 |
+
return scope;
|
6021 |
+
}
|
6022 |
+
items[id] = item;
|
6023 |
+
registerDefaults(item, scope, parentScope);
|
6024 |
+
if (this.override) {
|
6025 |
+
defaults.override(item.id, item.overrides);
|
6026 |
+
}
|
6027 |
+
return scope;
|
6028 |
+
}
|
6029 |
+
get(id) {
|
6030 |
+
return this.items[id];
|
6031 |
+
}
|
6032 |
+
unregister(item) {
|
6033 |
+
const items = this.items;
|
6034 |
+
const id = item.id;
|
6035 |
+
const scope = this.scope;
|
6036 |
+
if (id in items) {
|
6037 |
+
delete items[id];
|
6038 |
+
}
|
6039 |
+
if (scope && id in defaults[scope]) {
|
6040 |
+
delete defaults[scope][id];
|
6041 |
+
if (this.override) {
|
6042 |
+
delete overrides[id];
|
6043 |
+
}
|
6044 |
+
}
|
6045 |
+
}
|
6046 |
+
}
|
6047 |
+
function registerDefaults(item, scope, parentScope) {
|
6048 |
+
const itemDefaults = merge(Object.create(null), [
|
6049 |
+
parentScope ? defaults.get(parentScope) : {},
|
6050 |
+
defaults.get(scope),
|
6051 |
+
item.defaults
|
6052 |
+
]);
|
6053 |
+
defaults.set(scope, itemDefaults);
|
6054 |
+
if (item.defaultRoutes) {
|
6055 |
+
routeDefaults(scope, item.defaultRoutes);
|
6056 |
+
}
|
6057 |
+
if (item.descriptors) {
|
6058 |
+
defaults.describe(scope, item.descriptors);
|
6059 |
+
}
|
6060 |
+
}
|
6061 |
+
function routeDefaults(scope, routes) {
|
6062 |
+
Object.keys(routes).forEach(property => {
|
6063 |
+
const propertyParts = property.split('.');
|
6064 |
+
const sourceName = propertyParts.pop();
|
6065 |
+
const sourceScope = [scope].concat(propertyParts).join('.');
|
6066 |
+
const parts = routes[property].split('.');
|
6067 |
+
const targetName = parts.pop();
|
6068 |
+
const targetScope = parts.join('.');
|
6069 |
+
defaults.route(sourceScope, sourceName, targetScope, targetName);
|
6070 |
+
});
|
6071 |
+
}
|
6072 |
+
function isIChartComponent(proto) {
|
6073 |
+
return 'id' in proto && 'defaults' in proto;
|
6074 |
+
}
|
6075 |
+
|
6076 |
+
class Registry {
|
6077 |
+
constructor() {
|
6078 |
+
this.controllers = new TypedRegistry(DatasetController, 'datasets', true);
|
6079 |
+
this.elements = new TypedRegistry(Element, 'elements');
|
6080 |
+
this.plugins = new TypedRegistry(Object, 'plugins');
|
6081 |
+
this.scales = new TypedRegistry(Scale, 'scales');
|
6082 |
+
this._typedRegistries = [this.controllers, this.scales, this.elements];
|
6083 |
+
}
|
6084 |
+
add(...args) {
|
6085 |
+
this._each('register', args);
|
6086 |
+
}
|
6087 |
+
remove(...args) {
|
6088 |
+
this._each('unregister', args);
|
6089 |
+
}
|
6090 |
+
addControllers(...args) {
|
6091 |
+
this._each('register', args, this.controllers);
|
6092 |
+
}
|
6093 |
+
addElements(...args) {
|
6094 |
+
this._each('register', args, this.elements);
|
6095 |
+
}
|
6096 |
+
addPlugins(...args) {
|
6097 |
+
this._each('register', args, this.plugins);
|
6098 |
+
}
|
6099 |
+
addScales(...args) {
|
6100 |
+
this._each('register', args, this.scales);
|
6101 |
+
}
|
6102 |
+
getController(id) {
|
6103 |
+
return this._get(id, this.controllers, 'controller');
|
6104 |
+
}
|
6105 |
+
getElement(id) {
|
6106 |
+
return this._get(id, this.elements, 'element');
|
6107 |
+
}
|
6108 |
+
getPlugin(id) {
|
6109 |
+
return this._get(id, this.plugins, 'plugin');
|
6110 |
+
}
|
6111 |
+
getScale(id) {
|
6112 |
+
return this._get(id, this.scales, 'scale');
|
6113 |
+
}
|
6114 |
+
removeControllers(...args) {
|
6115 |
+
this._each('unregister', args, this.controllers);
|
6116 |
+
}
|
6117 |
+
removeElements(...args) {
|
6118 |
+
this._each('unregister', args, this.elements);
|
6119 |
+
}
|
6120 |
+
removePlugins(...args) {
|
6121 |
+
this._each('unregister', args, this.plugins);
|
6122 |
+
}
|
6123 |
+
removeScales(...args) {
|
6124 |
+
this._each('unregister', args, this.scales);
|
6125 |
+
}
|
6126 |
+
_each(method, args, typedRegistry) {
|
6127 |
+
[...args].forEach(arg => {
|
6128 |
+
const reg = typedRegistry || this._getRegistryForType(arg);
|
6129 |
+
if (typedRegistry || reg.isForType(arg) || (reg === this.plugins && arg.id)) {
|
6130 |
+
this._exec(method, reg, arg);
|
6131 |
+
} else {
|
6132 |
+
each(arg, item => {
|
6133 |
+
const itemReg = typedRegistry || this._getRegistryForType(item);
|
6134 |
+
this._exec(method, itemReg, item);
|
6135 |
+
});
|
6136 |
+
}
|
6137 |
+
});
|
6138 |
+
}
|
6139 |
+
_exec(method, registry, component) {
|
6140 |
+
const camelMethod = _capitalize(method);
|
6141 |
+
callback(component['before' + camelMethod], [], component);
|
6142 |
+
registry[method](component);
|
6143 |
+
callback(component['after' + camelMethod], [], component);
|
6144 |
+
}
|
6145 |
+
_getRegistryForType(type) {
|
6146 |
+
for (let i = 0; i < this._typedRegistries.length; i++) {
|
6147 |
+
const reg = this._typedRegistries[i];
|
6148 |
+
if (reg.isForType(type)) {
|
6149 |
+
return reg;
|
6150 |
+
}
|
6151 |
+
}
|
6152 |
+
return this.plugins;
|
6153 |
+
}
|
6154 |
+
_get(id, typedRegistry, type) {
|
6155 |
+
const item = typedRegistry.get(id);
|
6156 |
+
if (item === undefined) {
|
6157 |
+
throw new Error('"' + id + '" is not a registered ' + type + '.');
|
6158 |
+
}
|
6159 |
+
return item;
|
6160 |
+
}
|
6161 |
+
}
|
6162 |
+
var registry = new Registry();
|
6163 |
+
|
6164 |
+
class PluginService {
|
6165 |
+
constructor() {
|
6166 |
+
this._init = [];
|
6167 |
+
}
|
6168 |
+
notify(chart, hook, args, filter) {
|
6169 |
+
if (hook === 'beforeInit') {
|
6170 |
+
this._init = this._createDescriptors(chart, true);
|
6171 |
+
this._notify(this._init, chart, 'install');
|
6172 |
+
}
|
6173 |
+
const descriptors = filter ? this._descriptors(chart).filter(filter) : this._descriptors(chart);
|
6174 |
+
const result = this._notify(descriptors, chart, hook, args);
|
6175 |
+
if (hook === 'afterDestroy') {
|
6176 |
+
this._notify(descriptors, chart, 'stop');
|
6177 |
+
this._notify(this._init, chart, 'uninstall');
|
6178 |
+
}
|
6179 |
+
return result;
|
6180 |
+
}
|
6181 |
+
_notify(descriptors, chart, hook, args) {
|
6182 |
+
args = args || {};
|
6183 |
+
for (const descriptor of descriptors) {
|
6184 |
+
const plugin = descriptor.plugin;
|
6185 |
+
const method = plugin[hook];
|
6186 |
+
const params = [chart, args, descriptor.options];
|
6187 |
+
if (callback(method, params, plugin) === false && args.cancelable) {
|
6188 |
+
return false;
|
6189 |
+
}
|
6190 |
+
}
|
6191 |
+
return true;
|
6192 |
+
}
|
6193 |
+
invalidate() {
|
6194 |
+
if (!isNullOrUndef(this._cache)) {
|
6195 |
+
this._oldCache = this._cache;
|
6196 |
+
this._cache = undefined;
|
6197 |
+
}
|
6198 |
+
}
|
6199 |
+
_descriptors(chart) {
|
6200 |
+
if (this._cache) {
|
6201 |
+
return this._cache;
|
6202 |
+
}
|
6203 |
+
const descriptors = this._cache = this._createDescriptors(chart);
|
6204 |
+
this._notifyStateChanges(chart);
|
6205 |
+
return descriptors;
|
6206 |
+
}
|
6207 |
+
_createDescriptors(chart, all) {
|
6208 |
+
const config = chart && chart.config;
|
6209 |
+
const options = valueOrDefault(config.options && config.options.plugins, {});
|
6210 |
+
const plugins = allPlugins(config);
|
6211 |
+
return options === false && !all ? [] : createDescriptors(chart, plugins, options, all);
|
6212 |
+
}
|
6213 |
+
_notifyStateChanges(chart) {
|
6214 |
+
const previousDescriptors = this._oldCache || [];
|
6215 |
+
const descriptors = this._cache;
|
6216 |
+
const diff = (a, b) => a.filter(x => !b.some(y => x.plugin.id === y.plugin.id));
|
6217 |
+
this._notify(diff(previousDescriptors, descriptors), chart, 'stop');
|
6218 |
+
this._notify(diff(descriptors, previousDescriptors), chart, 'start');
|
6219 |
+
}
|
6220 |
+
}
|
6221 |
+
function allPlugins(config) {
|
6222 |
+
const plugins = [];
|
6223 |
+
const keys = Object.keys(registry.plugins.items);
|
6224 |
+
for (let i = 0; i < keys.length; i++) {
|
6225 |
+
plugins.push(registry.getPlugin(keys[i]));
|
6226 |
+
}
|
6227 |
+
const local = config.plugins || [];
|
6228 |
+
for (let i = 0; i < local.length; i++) {
|
6229 |
+
const plugin = local[i];
|
6230 |
+
if (plugins.indexOf(plugin) === -1) {
|
6231 |
+
plugins.push(plugin);
|
6232 |
+
}
|
6233 |
+
}
|
6234 |
+
return plugins;
|
6235 |
+
}
|
6236 |
+
function getOpts(options, all) {
|
6237 |
+
if (!all && options === false) {
|
6238 |
+
return null;
|
6239 |
+
}
|
6240 |
+
if (options === true) {
|
6241 |
+
return {};
|
6242 |
+
}
|
6243 |
+
return options;
|
6244 |
+
}
|
6245 |
+
function createDescriptors(chart, plugins, options, all) {
|
6246 |
+
const result = [];
|
6247 |
+
const context = chart.getContext();
|
6248 |
+
for (let i = 0; i < plugins.length; i++) {
|
6249 |
+
const plugin = plugins[i];
|
6250 |
+
const id = plugin.id;
|
6251 |
+
const opts = getOpts(options[id], all);
|
6252 |
+
if (opts === null) {
|
6253 |
+
continue;
|
6254 |
+
}
|
6255 |
+
result.push({
|
6256 |
+
plugin,
|
6257 |
+
options: pluginOpts(chart.config, plugin, opts, context)
|
6258 |
+
});
|
6259 |
+
}
|
6260 |
+
return result;
|
6261 |
+
}
|
6262 |
+
function pluginOpts(config, plugin, opts, context) {
|
6263 |
+
const keys = config.pluginScopeKeys(plugin);
|
6264 |
+
const scopes = config.getOptionScopes(opts, keys);
|
6265 |
+
return config.createResolver(scopes, context, [''], {scriptable: false, indexable: false, allKeys: true});
|
6266 |
+
}
|
6267 |
+
|
6268 |
+
function getIndexAxis(type, options) {
|
6269 |
+
const datasetDefaults = defaults.datasets[type] || {};
|
6270 |
+
const datasetOptions = (options.datasets || {})[type] || {};
|
6271 |
+
return datasetOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || 'x';
|
6272 |
+
}
|
6273 |
+
function getAxisFromDefaultScaleID(id, indexAxis) {
|
6274 |
+
let axis = id;
|
6275 |
+
if (id === '_index_') {
|
6276 |
+
axis = indexAxis;
|
6277 |
+
} else if (id === '_value_') {
|
6278 |
+
axis = indexAxis === 'x' ? 'y' : 'x';
|
6279 |
+
}
|
6280 |
+
return axis;
|
6281 |
+
}
|
6282 |
+
function getDefaultScaleIDFromAxis(axis, indexAxis) {
|
6283 |
+
return axis === indexAxis ? '_index_' : '_value_';
|
6284 |
+
}
|
6285 |
+
function axisFromPosition(position) {
|
6286 |
+
if (position === 'top' || position === 'bottom') {
|
6287 |
+
return 'x';
|
6288 |
+
}
|
6289 |
+
if (position === 'left' || position === 'right') {
|
6290 |
+
return 'y';
|
6291 |
+
}
|
6292 |
+
}
|
6293 |
+
function determineAxis(id, scaleOptions) {
|
6294 |
+
if (id === 'x' || id === 'y') {
|
6295 |
+
return id;
|
6296 |
+
}
|
6297 |
+
return scaleOptions.axis || axisFromPosition(scaleOptions.position) || id.charAt(0).toLowerCase();
|
6298 |
+
}
|
6299 |
+
function mergeScaleConfig(config, options) {
|
6300 |
+
const chartDefaults = overrides[config.type] || {scales: {}};
|
6301 |
+
const configScales = options.scales || {};
|
6302 |
+
const chartIndexAxis = getIndexAxis(config.type, options);
|
6303 |
+
const firstIDs = Object.create(null);
|
6304 |
+
const scales = Object.create(null);
|
6305 |
+
Object.keys(configScales).forEach(id => {
|
6306 |
+
const scaleConf = configScales[id];
|
6307 |
+
if (!isObject(scaleConf)) {
|
6308 |
+
return console.error(`Invalid scale configuration for scale: ${id}`);
|
6309 |
+
}
|
6310 |
+
if (scaleConf._proxy) {
|
6311 |
+
return console.warn(`Ignoring resolver passed as options for scale: ${id}`);
|
6312 |
+
}
|
6313 |
+
const axis = determineAxis(id, scaleConf);
|
6314 |
+
const defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis);
|
6315 |
+
const defaultScaleOptions = chartDefaults.scales || {};
|
6316 |
+
firstIDs[axis] = firstIDs[axis] || id;
|
6317 |
+
scales[id] = mergeIf(Object.create(null), [{axis}, scaleConf, defaultScaleOptions[axis], defaultScaleOptions[defaultId]]);
|
6318 |
+
});
|
6319 |
+
config.data.datasets.forEach(dataset => {
|
6320 |
+
const type = dataset.type || config.type;
|
6321 |
+
const indexAxis = dataset.indexAxis || getIndexAxis(type, options);
|
6322 |
+
const datasetDefaults = overrides[type] || {};
|
6323 |
+
const defaultScaleOptions = datasetDefaults.scales || {};
|
6324 |
+
Object.keys(defaultScaleOptions).forEach(defaultID => {
|
6325 |
+
const axis = getAxisFromDefaultScaleID(defaultID, indexAxis);
|
6326 |
+
const id = dataset[axis + 'AxisID'] || firstIDs[axis] || axis;
|
6327 |
+
scales[id] = scales[id] || Object.create(null);
|
6328 |
+
mergeIf(scales[id], [{axis}, configScales[id], defaultScaleOptions[defaultID]]);
|
6329 |
+
});
|
6330 |
+
});
|
6331 |
+
Object.keys(scales).forEach(key => {
|
6332 |
+
const scale = scales[key];
|
6333 |
+
mergeIf(scale, [defaults.scales[scale.type], defaults.scale]);
|
6334 |
+
});
|
6335 |
+
return scales;
|
6336 |
+
}
|
6337 |
+
function initOptions(config) {
|
6338 |
+
const options = config.options || (config.options = {});
|
6339 |
+
options.plugins = valueOrDefault(options.plugins, {});
|
6340 |
+
options.scales = mergeScaleConfig(config, options);
|
6341 |
+
}
|
6342 |
+
function initData(data) {
|
6343 |
+
data = data || {};
|
6344 |
+
data.datasets = data.datasets || [];
|
6345 |
+
data.labels = data.labels || [];
|
6346 |
+
return data;
|
6347 |
+
}
|
6348 |
+
function initConfig(config) {
|
6349 |
+
config = config || {};
|
6350 |
+
config.data = initData(config.data);
|
6351 |
+
initOptions(config);
|
6352 |
+
return config;
|
6353 |
+
}
|
6354 |
+
const keyCache = new Map();
|
6355 |
+
const keysCached = new Set();
|
6356 |
+
function cachedKeys(cacheKey, generate) {
|
6357 |
+
let keys = keyCache.get(cacheKey);
|
6358 |
+
if (!keys) {
|
6359 |
+
keys = generate();
|
6360 |
+
keyCache.set(cacheKey, keys);
|
6361 |
+
keysCached.add(keys);
|
6362 |
+
}
|
6363 |
+
return keys;
|
6364 |
+
}
|
6365 |
+
const addIfFound = (set, obj, key) => {
|
6366 |
+
const opts = resolveObjectKey(obj, key);
|
6367 |
+
if (opts !== undefined) {
|
6368 |
+
set.add(opts);
|
6369 |
+
}
|
6370 |
+
};
|
6371 |
+
class Config {
|
6372 |
+
constructor(config) {
|
6373 |
+
this._config = initConfig(config);
|
6374 |
+
this._scopeCache = new Map();
|
6375 |
+
this._resolverCache = new Map();
|
6376 |
+
}
|
6377 |
+
get platform() {
|
6378 |
+
return this._config.platform;
|
6379 |
+
}
|
6380 |
+
get type() {
|
6381 |
+
return this._config.type;
|
6382 |
+
}
|
6383 |
+
set type(type) {
|
6384 |
+
this._config.type = type;
|
6385 |
+
}
|
6386 |
+
get data() {
|
6387 |
+
return this._config.data;
|
6388 |
+
}
|
6389 |
+
set data(data) {
|
6390 |
+
this._config.data = initData(data);
|
6391 |
+
}
|
6392 |
+
get options() {
|
6393 |
+
return this._config.options;
|
6394 |
+
}
|
6395 |
+
set options(options) {
|
6396 |
+
this._config.options = options;
|
6397 |
+
}
|
6398 |
+
get plugins() {
|
6399 |
+
return this._config.plugins;
|
6400 |
+
}
|
6401 |
+
update() {
|
6402 |
+
const config = this._config;
|
6403 |
+
this.clearCache();
|
6404 |
+
initOptions(config);
|
6405 |
+
}
|
6406 |
+
clearCache() {
|
6407 |
+
this._scopeCache.clear();
|
6408 |
+
this._resolverCache.clear();
|
6409 |
+
}
|
6410 |
+
datasetScopeKeys(datasetType) {
|
6411 |
+
return cachedKeys(datasetType,
|
6412 |
+
() => [[
|
6413 |
+
`datasets.${datasetType}`,
|
6414 |
+
''
|
6415 |
+
]]);
|
6416 |
+
}
|
6417 |
+
datasetAnimationScopeKeys(datasetType, transition) {
|
6418 |
+
return cachedKeys(`${datasetType}.transition.${transition}`,
|
6419 |
+
() => [
|
6420 |
+
[
|
6421 |
+
`datasets.${datasetType}.transitions.${transition}`,
|
6422 |
+
`transitions.${transition}`,
|
6423 |
+
],
|
6424 |
+
[
|
6425 |
+
`datasets.${datasetType}`,
|
6426 |
+
''
|
6427 |
+
]
|
6428 |
+
]);
|
6429 |
+
}
|
6430 |
+
datasetElementScopeKeys(datasetType, elementType) {
|
6431 |
+
return cachedKeys(`${datasetType}-${elementType}`,
|
6432 |
+
() => [[
|
6433 |
+
`datasets.${datasetType}.elements.${elementType}`,
|
6434 |
+
`datasets.${datasetType}`,
|
6435 |
+
`elements.${elementType}`,
|
6436 |
+
''
|
6437 |
+
]]);
|
6438 |
+
}
|
6439 |
+
pluginScopeKeys(plugin) {
|
6440 |
+
const id = plugin.id;
|
6441 |
+
const type = this.type;
|
6442 |
+
return cachedKeys(`${type}-plugin-${id}`,
|
6443 |
+
() => [[
|
6444 |
+
`plugins.${id}`,
|
6445 |
+
...plugin.additionalOptionScopes || [],
|
6446 |
+
]]);
|
6447 |
+
}
|
6448 |
+
_cachedScopes(mainScope, resetCache) {
|
6449 |
+
const _scopeCache = this._scopeCache;
|
6450 |
+
let cache = _scopeCache.get(mainScope);
|
6451 |
+
if (!cache || resetCache) {
|
6452 |
+
cache = new Map();
|
6453 |
+
_scopeCache.set(mainScope, cache);
|
6454 |
+
}
|
6455 |
+
return cache;
|
6456 |
+
}
|
6457 |
+
getOptionScopes(mainScope, keyLists, resetCache) {
|
6458 |
+
const {options, type} = this;
|
6459 |
+
const cache = this._cachedScopes(mainScope, resetCache);
|
6460 |
+
const cached = cache.get(keyLists);
|
6461 |
+
if (cached) {
|
6462 |
+
return cached;
|
6463 |
+
}
|
6464 |
+
const scopes = new Set();
|
6465 |
+
keyLists.forEach(keys => {
|
6466 |
+
if (mainScope) {
|
6467 |
+
scopes.add(mainScope);
|
6468 |
+
keys.forEach(key => addIfFound(scopes, mainScope, key));
|
6469 |
+
}
|
6470 |
+
keys.forEach(key => addIfFound(scopes, options, key));
|
6471 |
+
keys.forEach(key => addIfFound(scopes, overrides[type] || {}, key));
|
6472 |
+
keys.forEach(key => addIfFound(scopes, defaults, key));
|
6473 |
+
keys.forEach(key => addIfFound(scopes, descriptors, key));
|
6474 |
+
});
|
6475 |
+
const array = Array.from(scopes);
|
6476 |
+
if (array.length === 0) {
|
6477 |
+
array.push(Object.create(null));
|
6478 |
+
}
|
6479 |
+
if (keysCached.has(keyLists)) {
|
6480 |
+
cache.set(keyLists, array);
|
6481 |
+
}
|
6482 |
+
return array;
|
6483 |
+
}
|
6484 |
+
chartOptionScopes() {
|
6485 |
+
const {options, type} = this;
|
6486 |
+
return [
|
6487 |
+
options,
|
6488 |
+
overrides[type] || {},
|
6489 |
+
defaults.datasets[type] || {},
|
6490 |
+
{type},
|
6491 |
+
defaults,
|
6492 |
+
descriptors
|
6493 |
+
];
|
6494 |
+
}
|
6495 |
+
resolveNamedOptions(scopes, names, context, prefixes = ['']) {
|
6496 |
+
const result = {$shared: true};
|
6497 |
+
const {resolver, subPrefixes} = getResolver(this._resolverCache, scopes, prefixes);
|
6498 |
+
let options = resolver;
|
6499 |
+
if (needContext(resolver, names)) {
|
6500 |
+
result.$shared = false;
|
6501 |
+
context = isFunction(context) ? context() : context;
|
6502 |
+
const subResolver = this.createResolver(scopes, context, subPrefixes);
|
6503 |
+
options = _attachContext(resolver, context, subResolver);
|
6504 |
+
}
|
6505 |
+
for (const prop of names) {
|
6506 |
+
result[prop] = options[prop];
|
6507 |
+
}
|
6508 |
+
return result;
|
6509 |
+
}
|
6510 |
+
createResolver(scopes, context, prefixes = [''], descriptorDefaults) {
|
6511 |
+
const {resolver} = getResolver(this._resolverCache, scopes, prefixes);
|
6512 |
+
return isObject(context)
|
6513 |
+
? _attachContext(resolver, context, undefined, descriptorDefaults)
|
6514 |
+
: resolver;
|
6515 |
+
}
|
6516 |
+
}
|
6517 |
+
function getResolver(resolverCache, scopes, prefixes) {
|
6518 |
+
let cache = resolverCache.get(scopes);
|
6519 |
+
if (!cache) {
|
6520 |
+
cache = new Map();
|
6521 |
+
resolverCache.set(scopes, cache);
|
6522 |
+
}
|
6523 |
+
const cacheKey = prefixes.join();
|
6524 |
+
let cached = cache.get(cacheKey);
|
6525 |
+
if (!cached) {
|
6526 |
+
const resolver = _createResolver(scopes, prefixes);
|
6527 |
+
cached = {
|
6528 |
+
resolver,
|
6529 |
+
subPrefixes: prefixes.filter(p => !p.toLowerCase().includes('hover'))
|
6530 |
+
};
|
6531 |
+
cache.set(cacheKey, cached);
|
6532 |
+
}
|
6533 |
+
return cached;
|
6534 |
+
}
|
6535 |
+
const hasFunction = value => isObject(value)
|
6536 |
+
&& Object.getOwnPropertyNames(value).reduce((acc, key) => acc || isFunction(value[key]), false);
|
6537 |
+
function needContext(proxy, names) {
|
6538 |
+
const {isScriptable, isIndexable} = _descriptors(proxy);
|
6539 |
+
for (const prop of names) {
|
6540 |
+
const scriptable = isScriptable(prop);
|
6541 |
+
const indexable = isIndexable(prop);
|
6542 |
+
const value = (indexable || scriptable) && proxy[prop];
|
6543 |
+
if ((scriptable && (isFunction(value) || hasFunction(value)))
|
6544 |
+
|| (indexable && isArray(value))) {
|
6545 |
+
return true;
|
6546 |
+
}
|
6547 |
+
}
|
6548 |
+
return false;
|
6549 |
+
}
|
6550 |
+
|
6551 |
+
var version = "3.7.1";
|
6552 |
+
|
6553 |
+
const KNOWN_POSITIONS = ['top', 'bottom', 'left', 'right', 'chartArea'];
|
6554 |
+
function positionIsHorizontal(position, axis) {
|
6555 |
+
return position === 'top' || position === 'bottom' || (KNOWN_POSITIONS.indexOf(position) === -1 && axis === 'x');
|
6556 |
+
}
|
6557 |
+
function compare2Level(l1, l2) {
|
6558 |
+
return function(a, b) {
|
6559 |
+
return a[l1] === b[l1]
|
6560 |
+
? a[l2] - b[l2]
|
6561 |
+
: a[l1] - b[l1];
|
6562 |
+
};
|
6563 |
+
}
|
6564 |
+
function onAnimationsComplete(context) {
|
6565 |
+
const chart = context.chart;
|
6566 |
+
const animationOptions = chart.options.animation;
|
6567 |
+
chart.notifyPlugins('afterRender');
|
6568 |
+
callback(animationOptions && animationOptions.onComplete, [context], chart);
|
6569 |
+
}
|
6570 |
+
function onAnimationProgress(context) {
|
6571 |
+
const chart = context.chart;
|
6572 |
+
const animationOptions = chart.options.animation;
|
6573 |
+
callback(animationOptions && animationOptions.onProgress, [context], chart);
|
6574 |
+
}
|
6575 |
+
function getCanvas(item) {
|
6576 |
+
if (_isDomSupported() && typeof item === 'string') {
|
6577 |
+
item = document.getElementById(item);
|
6578 |
+
} else if (item && item.length) {
|
6579 |
+
item = item[0];
|
6580 |
+
}
|
6581 |
+
if (item && item.canvas) {
|
6582 |
+
item = item.canvas;
|
6583 |
+
}
|
6584 |
+
return item;
|
6585 |
+
}
|
6586 |
+
const instances = {};
|
6587 |
+
const getChart = (key) => {
|
6588 |
+
const canvas = getCanvas(key);
|
6589 |
+
return Object.values(instances).filter((c) => c.canvas === canvas).pop();
|
6590 |
+
};
|
6591 |
+
function moveNumericKeys(obj, start, move) {
|
6592 |
+
const keys = Object.keys(obj);
|
6593 |
+
for (const key of keys) {
|
6594 |
+
const intKey = +key;
|
6595 |
+
if (intKey >= start) {
|
6596 |
+
const value = obj[key];
|
6597 |
+
delete obj[key];
|
6598 |
+
if (move > 0 || intKey > start) {
|
6599 |
+
obj[intKey + move] = value;
|
6600 |
+
}
|
6601 |
+
}
|
6602 |
+
}
|
6603 |
+
}
|
6604 |
+
function determineLastEvent(e, lastEvent, inChartArea, isClick) {
|
6605 |
+
if (!inChartArea || e.type === 'mouseout') {
|
6606 |
+
return null;
|
6607 |
+
}
|
6608 |
+
if (isClick) {
|
6609 |
+
return lastEvent;
|
6610 |
+
}
|
6611 |
+
return e;
|
6612 |
+
}
|
6613 |
+
class Chart {
|
6614 |
+
constructor(item, userConfig) {
|
6615 |
+
const config = this.config = new Config(userConfig);
|
6616 |
+
const initialCanvas = getCanvas(item);
|
6617 |
+
const existingChart = getChart(initialCanvas);
|
6618 |
+
if (existingChart) {
|
6619 |
+
throw new Error(
|
6620 |
+
'Canvas is already in use. Chart with ID \'' + existingChart.id + '\'' +
|
6621 |
+
' must be destroyed before the canvas can be reused.'
|
6622 |
+
);
|
6623 |
+
}
|
6624 |
+
const options = config.createResolver(config.chartOptionScopes(), this.getContext());
|
6625 |
+
this.platform = new (config.platform || _detectPlatform(initialCanvas))();
|
6626 |
+
this.platform.updateConfig(config);
|
6627 |
+
const context = this.platform.acquireContext(initialCanvas, options.aspectRatio);
|
6628 |
+
const canvas = context && context.canvas;
|
6629 |
+
const height = canvas && canvas.height;
|
6630 |
+
const width = canvas && canvas.width;
|
6631 |
+
this.id = uid();
|
6632 |
+
this.ctx = context;
|
6633 |
+
this.canvas = canvas;
|
6634 |
+
this.width = width;
|
6635 |
+
this.height = height;
|
6636 |
+
this._options = options;
|
6637 |
+
this._aspectRatio = this.aspectRatio;
|
6638 |
+
this._layers = [];
|
6639 |
+
this._metasets = [];
|
6640 |
+
this._stacks = undefined;
|
6641 |
+
this.boxes = [];
|
6642 |
+
this.currentDevicePixelRatio = undefined;
|
6643 |
+
this.chartArea = undefined;
|
6644 |
+
this._active = [];
|
6645 |
+
this._lastEvent = undefined;
|
6646 |
+
this._listeners = {};
|
6647 |
+
this._responsiveListeners = undefined;
|
6648 |
+
this._sortedMetasets = [];
|
6649 |
+
this.scales = {};
|
6650 |
+
this._plugins = new PluginService();
|
6651 |
+
this.$proxies = {};
|
6652 |
+
this._hiddenIndices = {};
|
6653 |
+
this.attached = false;
|
6654 |
+
this._animationsDisabled = undefined;
|
6655 |
+
this.$context = undefined;
|
6656 |
+
this._doResize = debounce(mode => this.update(mode), options.resizeDelay || 0);
|
6657 |
+
this._dataChanges = [];
|
6658 |
+
instances[this.id] = this;
|
6659 |
+
if (!context || !canvas) {
|
6660 |
+
console.error("Failed to create chart: can't acquire context from the given item");
|
6661 |
+
return;
|
6662 |
+
}
|
6663 |
+
animator.listen(this, 'complete', onAnimationsComplete);
|
6664 |
+
animator.listen(this, 'progress', onAnimationProgress);
|
6665 |
+
this._initialize();
|
6666 |
+
if (this.attached) {
|
6667 |
+
this.update();
|
6668 |
+
}
|
6669 |
+
}
|
6670 |
+
get aspectRatio() {
|
6671 |
+
const {options: {aspectRatio, maintainAspectRatio}, width, height, _aspectRatio} = this;
|
6672 |
+
if (!isNullOrUndef(aspectRatio)) {
|
6673 |
+
return aspectRatio;
|
6674 |
+
}
|
6675 |
+
if (maintainAspectRatio && _aspectRatio) {
|
6676 |
+
return _aspectRatio;
|
6677 |
+
}
|
6678 |
+
return height ? width / height : null;
|
6679 |
+
}
|
6680 |
+
get data() {
|
6681 |
+
return this.config.data;
|
6682 |
+
}
|
6683 |
+
set data(data) {
|
6684 |
+
this.config.data = data;
|
6685 |
+
}
|
6686 |
+
get options() {
|
6687 |
+
return this._options;
|
6688 |
+
}
|
6689 |
+
set options(options) {
|
6690 |
+
this.config.options = options;
|
6691 |
+
}
|
6692 |
+
_initialize() {
|
6693 |
+
this.notifyPlugins('beforeInit');
|
6694 |
+
if (this.options.responsive) {
|
6695 |
+
this.resize();
|
6696 |
+
} else {
|
6697 |
+
retinaScale(this, this.options.devicePixelRatio);
|
6698 |
+
}
|
6699 |
+
this.bindEvents();
|
6700 |
+
this.notifyPlugins('afterInit');
|
6701 |
+
return this;
|
6702 |
+
}
|
6703 |
+
clear() {
|
6704 |
+
clearCanvas(this.canvas, this.ctx);
|
6705 |
+
return this;
|
6706 |
+
}
|
6707 |
+
stop() {
|
6708 |
+
animator.stop(this);
|
6709 |
+
return this;
|
6710 |
+
}
|
6711 |
+
resize(width, height) {
|
6712 |
+
if (!animator.running(this)) {
|
6713 |
+
this._resize(width, height);
|
6714 |
+
} else {
|
6715 |
+
this._resizeBeforeDraw = {width, height};
|
6716 |
+
}
|
6717 |
+
}
|
6718 |
+
_resize(width, height) {
|
6719 |
+
const options = this.options;
|
6720 |
+
const canvas = this.canvas;
|
6721 |
+
const aspectRatio = options.maintainAspectRatio && this.aspectRatio;
|
6722 |
+
const newSize = this.platform.getMaximumSize(canvas, width, height, aspectRatio);
|
6723 |
+
const newRatio = options.devicePixelRatio || this.platform.getDevicePixelRatio();
|
6724 |
+
const mode = this.width ? 'resize' : 'attach';
|
6725 |
+
this.width = newSize.width;
|
6726 |
+
this.height = newSize.height;
|
6727 |
+
this._aspectRatio = this.aspectRatio;
|
6728 |
+
if (!retinaScale(this, newRatio, true)) {
|
6729 |
+
return;
|
6730 |
+
}
|
6731 |
+
this.notifyPlugins('resize', {size: newSize});
|
6732 |
+
callback(options.onResize, [this, newSize], this);
|
6733 |
+
if (this.attached) {
|
6734 |
+
if (this._doResize(mode)) {
|
6735 |
+
this.render();
|
6736 |
+
}
|
6737 |
+
}
|
6738 |
+
}
|
6739 |
+
ensureScalesHaveIDs() {
|
6740 |
+
const options = this.options;
|
6741 |
+
const scalesOptions = options.scales || {};
|
6742 |
+
each(scalesOptions, (axisOptions, axisID) => {
|
6743 |
+
axisOptions.id = axisID;
|
6744 |
+
});
|
6745 |
+
}
|
6746 |
+
buildOrUpdateScales() {
|
6747 |
+
const options = this.options;
|
6748 |
+
const scaleOpts = options.scales;
|
6749 |
+
const scales = this.scales;
|
6750 |
+
const updated = Object.keys(scales).reduce((obj, id) => {
|
6751 |
+
obj[id] = false;
|
6752 |
+
return obj;
|
6753 |
+
}, {});
|
6754 |
+
let items = [];
|
6755 |
+
if (scaleOpts) {
|
6756 |
+
items = items.concat(
|
6757 |
+
Object.keys(scaleOpts).map((id) => {
|
6758 |
+
const scaleOptions = scaleOpts[id];
|
6759 |
+
const axis = determineAxis(id, scaleOptions);
|
6760 |
+
const isRadial = axis === 'r';
|
6761 |
+
const isHorizontal = axis === 'x';
|
6762 |
+
return {
|
6763 |
+
options: scaleOptions,
|
6764 |
+
dposition: isRadial ? 'chartArea' : isHorizontal ? 'bottom' : 'left',
|
6765 |
+
dtype: isRadial ? 'radialLinear' : isHorizontal ? 'category' : 'linear'
|
6766 |
+
};
|
6767 |
+
})
|
6768 |
+
);
|
6769 |
+
}
|
6770 |
+
each(items, (item) => {
|
6771 |
+
const scaleOptions = item.options;
|
6772 |
+
const id = scaleOptions.id;
|
6773 |
+
const axis = determineAxis(id, scaleOptions);
|
6774 |
+
const scaleType = valueOrDefault(scaleOptions.type, item.dtype);
|
6775 |
+
if (scaleOptions.position === undefined || positionIsHorizontal(scaleOptions.position, axis) !== positionIsHorizontal(item.dposition)) {
|
6776 |
+
scaleOptions.position = item.dposition;
|
6777 |
+
}
|
6778 |
+
updated[id] = true;
|
6779 |
+
let scale = null;
|
6780 |
+
if (id in scales && scales[id].type === scaleType) {
|
6781 |
+
scale = scales[id];
|
6782 |
+
} else {
|
6783 |
+
const scaleClass = registry.getScale(scaleType);
|
6784 |
+
scale = new scaleClass({
|
6785 |
+
id,
|
6786 |
+
type: scaleType,
|
6787 |
+
ctx: this.ctx,
|
6788 |
+
chart: this
|
6789 |
+
});
|
6790 |
+
scales[scale.id] = scale;
|
6791 |
+
}
|
6792 |
+
scale.init(scaleOptions, options);
|
6793 |
+
});
|
6794 |
+
each(updated, (hasUpdated, id) => {
|
6795 |
+
if (!hasUpdated) {
|
6796 |
+
delete scales[id];
|
6797 |
+
}
|
6798 |
+
});
|
6799 |
+
each(scales, (scale) => {
|
6800 |
+
layouts.configure(this, scale, scale.options);
|
6801 |
+
layouts.addBox(this, scale);
|
6802 |
+
});
|
6803 |
+
}
|
6804 |
+
_updateMetasets() {
|
6805 |
+
const metasets = this._metasets;
|
6806 |
+
const numData = this.data.datasets.length;
|
6807 |
+
const numMeta = metasets.length;
|
6808 |
+
metasets.sort((a, b) => a.index - b.index);
|
6809 |
+
if (numMeta > numData) {
|
6810 |
+
for (let i = numData; i < numMeta; ++i) {
|
6811 |
+
this._destroyDatasetMeta(i);
|
6812 |
+
}
|
6813 |
+
metasets.splice(numData, numMeta - numData);
|
6814 |
+
}
|
6815 |
+
this._sortedMetasets = metasets.slice(0).sort(compare2Level('order', 'index'));
|
6816 |
+
}
|
6817 |
+
_removeUnreferencedMetasets() {
|
6818 |
+
const {_metasets: metasets, data: {datasets}} = this;
|
6819 |
+
if (metasets.length > datasets.length) {
|
6820 |
+
delete this._stacks;
|
6821 |
+
}
|
6822 |
+
metasets.forEach((meta, index) => {
|
6823 |
+
if (datasets.filter(x => x === meta._dataset).length === 0) {
|
6824 |
+
this._destroyDatasetMeta(index);
|
6825 |
+
}
|
6826 |
+
});
|
6827 |
+
}
|
6828 |
+
buildOrUpdateControllers() {
|
6829 |
+
const newControllers = [];
|
6830 |
+
const datasets = this.data.datasets;
|
6831 |
+
let i, ilen;
|
6832 |
+
this._removeUnreferencedMetasets();
|
6833 |
+
for (i = 0, ilen = datasets.length; i < ilen; i++) {
|
6834 |
+
const dataset = datasets[i];
|
6835 |
+
let meta = this.getDatasetMeta(i);
|
6836 |
+
const type = dataset.type || this.config.type;
|
6837 |
+
if (meta.type && meta.type !== type) {
|
6838 |
+
this._destroyDatasetMeta(i);
|
6839 |
+
meta = this.getDatasetMeta(i);
|
6840 |
+
}
|
6841 |
+
meta.type = type;
|
6842 |
+
meta.indexAxis = dataset.indexAxis || getIndexAxis(type, this.options);
|
6843 |
+
meta.order = dataset.order || 0;
|
6844 |
+
meta.index = i;
|
6845 |
+
meta.label = '' + dataset.label;
|
6846 |
+
meta.visible = this.isDatasetVisible(i);
|
6847 |
+
if (meta.controller) {
|
6848 |
+
meta.controller.updateIndex(i);
|
6849 |
+
meta.controller.linkScales();
|
6850 |
+
} else {
|
6851 |
+
const ControllerClass = registry.getController(type);
|
6852 |
+
const {datasetElementType, dataElementType} = defaults.datasets[type];
|
6853 |
+
Object.assign(ControllerClass.prototype, {
|
6854 |
+
dataElementType: registry.getElement(dataElementType),
|
6855 |
+
datasetElementType: datasetElementType && registry.getElement(datasetElementType)
|
6856 |
+
});
|
6857 |
+
meta.controller = new ControllerClass(this, i);
|
6858 |
+
newControllers.push(meta.controller);
|
6859 |
+
}
|
6860 |
+
}
|
6861 |
+
this._updateMetasets();
|
6862 |
+
return newControllers;
|
6863 |
+
}
|
6864 |
+
_resetElements() {
|
6865 |
+
each(this.data.datasets, (dataset, datasetIndex) => {
|
6866 |
+
this.getDatasetMeta(datasetIndex).controller.reset();
|
6867 |
+
}, this);
|
6868 |
+
}
|
6869 |
+
reset() {
|
6870 |
+
this._resetElements();
|
6871 |
+
this.notifyPlugins('reset');
|
6872 |
+
}
|
6873 |
+
update(mode) {
|
6874 |
+
const config = this.config;
|
6875 |
+
config.update();
|
6876 |
+
const options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext());
|
6877 |
+
const animsDisabled = this._animationsDisabled = !options.animation;
|
6878 |
+
this._updateScales();
|
6879 |
+
this._checkEventBindings();
|
6880 |
+
this._updateHiddenIndices();
|
6881 |
+
this._plugins.invalidate();
|
6882 |
+
if (this.notifyPlugins('beforeUpdate', {mode, cancelable: true}) === false) {
|
6883 |
+
return;
|
6884 |
+
}
|
6885 |
+
const newControllers = this.buildOrUpdateControllers();
|
6886 |
+
this.notifyPlugins('beforeElementsUpdate');
|
6887 |
+
let minPadding = 0;
|
6888 |
+
for (let i = 0, ilen = this.data.datasets.length; i < ilen; i++) {
|
6889 |
+
const {controller} = this.getDatasetMeta(i);
|
6890 |
+
const reset = !animsDisabled && newControllers.indexOf(controller) === -1;
|
6891 |
+
controller.buildOrUpdateElements(reset);
|
6892 |
+
minPadding = Math.max(+controller.getMaxOverflow(), minPadding);
|
6893 |
+
}
|
6894 |
+
minPadding = this._minPadding = options.layout.autoPadding ? minPadding : 0;
|
6895 |
+
this._updateLayout(minPadding);
|
6896 |
+
if (!animsDisabled) {
|
6897 |
+
each(newControllers, (controller) => {
|
6898 |
+
controller.reset();
|
6899 |
+
});
|
6900 |
+
}
|
6901 |
+
this._updateDatasets(mode);
|
6902 |
+
this.notifyPlugins('afterUpdate', {mode});
|
6903 |
+
this._layers.sort(compare2Level('z', '_idx'));
|
6904 |
+
const {_active, _lastEvent} = this;
|
6905 |
+
if (_lastEvent) {
|
6906 |
+
this._eventHandler(_lastEvent, true);
|
6907 |
+
} else if (_active.length) {
|
6908 |
+
this._updateHoverStyles(_active, _active, true);
|
6909 |
+
}
|
6910 |
+
this.render();
|
6911 |
+
}
|
6912 |
+
_updateScales() {
|
6913 |
+
each(this.scales, (scale) => {
|
6914 |
+
layouts.removeBox(this, scale);
|
6915 |
+
});
|
6916 |
+
this.ensureScalesHaveIDs();
|
6917 |
+
this.buildOrUpdateScales();
|
6918 |
+
}
|
6919 |
+
_checkEventBindings() {
|
6920 |
+
const options = this.options;
|
6921 |
+
const existingEvents = new Set(Object.keys(this._listeners));
|
6922 |
+
const newEvents = new Set(options.events);
|
6923 |
+
if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) {
|
6924 |
+
this.unbindEvents();
|
6925 |
+
this.bindEvents();
|
6926 |
+
}
|
6927 |
+
}
|
6928 |
+
_updateHiddenIndices() {
|
6929 |
+
const {_hiddenIndices} = this;
|
6930 |
+
const changes = this._getUniformDataChanges() || [];
|
6931 |
+
for (const {method, start, count} of changes) {
|
6932 |
+
const move = method === '_removeElements' ? -count : count;
|
6933 |
+
moveNumericKeys(_hiddenIndices, start, move);
|
6934 |
+
}
|
6935 |
+
}
|
6936 |
+
_getUniformDataChanges() {
|
6937 |
+
const _dataChanges = this._dataChanges;
|
6938 |
+
if (!_dataChanges || !_dataChanges.length) {
|
6939 |
+
return;
|
6940 |
+
}
|
6941 |
+
this._dataChanges = [];
|
6942 |
+
const datasetCount = this.data.datasets.length;
|
6943 |
+
const makeSet = (idx) => new Set(
|
6944 |
+
_dataChanges
|
6945 |
+
.filter(c => c[0] === idx)
|
6946 |
+
.map((c, i) => i + ',' + c.splice(1).join(','))
|
6947 |
);
|
6948 |
+
const changeSet = makeSet(0);
|
6949 |
+
for (let i = 1; i < datasetCount; i++) {
|
6950 |
+
if (!setsEqual(changeSet, makeSet(i))) {
|
6951 |
+
return;
|
6952 |
+
}
|
6953 |
+
}
|
6954 |
+
return Array.from(changeSet)
|
6955 |
+
.map(c => c.split(','))
|
6956 |
+
.map(a => ({method: a[1], start: +a[2], count: +a[3]}));
|
6957 |
+
}
|
6958 |
+
_updateLayout(minPadding) {
|
6959 |
+
if (this.notifyPlugins('beforeLayout', {cancelable: true}) === false) {
|
6960 |
+
return;
|
6961 |
+
}
|
6962 |
+
layouts.update(this, this.width, this.height, minPadding);
|
6963 |
+
const area = this.chartArea;
|
6964 |
+
const noArea = area.width <= 0 || area.height <= 0;
|
6965 |
+
this._layers = [];
|
6966 |
+
each(this.boxes, (box) => {
|
6967 |
+
if (noArea && box.position === 'chartArea') {
|
6968 |
+
return;
|
6969 |
+
}
|
6970 |
+
if (box.configure) {
|
6971 |
+
box.configure();
|
6972 |
+
}
|
6973 |
+
this._layers.push(...box._layers());
|
6974 |
+
}, this);
|
6975 |
+
this._layers.forEach((item, index) => {
|
6976 |
+
item._idx = index;
|
6977 |
+
});
|
6978 |
+
this.notifyPlugins('afterLayout');
|
6979 |
+
}
|
6980 |
+
_updateDatasets(mode) {
|
6981 |
+
if (this.notifyPlugins('beforeDatasetsUpdate', {mode, cancelable: true}) === false) {
|
6982 |
+
return;
|
6983 |
+
}
|
6984 |
+
for (let i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
|
6985 |
+
this.getDatasetMeta(i).controller.configure();
|
6986 |
+
}
|
6987 |
+
for (let i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
|
6988 |
+
this._updateDataset(i, isFunction(mode) ? mode({datasetIndex: i}) : mode);
|
6989 |
+
}
|
6990 |
+
this.notifyPlugins('afterDatasetsUpdate', {mode});
|
6991 |
+
}
|
6992 |
+
_updateDataset(index, mode) {
|
6993 |
+
const meta = this.getDatasetMeta(index);
|
6994 |
+
const args = {meta, index, mode, cancelable: true};
|
6995 |
+
if (this.notifyPlugins('beforeDatasetUpdate', args) === false) {
|
6996 |
+
return;
|
6997 |
+
}
|
6998 |
+
meta.controller._update(mode);
|
6999 |
+
args.cancelable = false;
|
7000 |
+
this.notifyPlugins('afterDatasetUpdate', args);
|
7001 |
+
}
|
7002 |
+
render() {
|
7003 |
+
if (this.notifyPlugins('beforeRender', {cancelable: true}) === false) {
|
7004 |
+
return;
|
7005 |
+
}
|
7006 |
+
if (animator.has(this)) {
|
7007 |
+
if (this.attached && !animator.running(this)) {
|
7008 |
+
animator.start(this);
|
7009 |
+
}
|
7010 |
+
} else {
|
7011 |
+
this.draw();
|
7012 |
+
onAnimationsComplete({chart: this});
|
7013 |
+
}
|
7014 |
+
}
|
7015 |
+
draw() {
|
7016 |
+
let i;
|
7017 |
+
if (this._resizeBeforeDraw) {
|
7018 |
+
const {width, height} = this._resizeBeforeDraw;
|
7019 |
+
this._resize(width, height);
|
7020 |
+
this._resizeBeforeDraw = null;
|
7021 |
+
}
|
7022 |
+
this.clear();
|
7023 |
+
if (this.width <= 0 || this.height <= 0) {
|
7024 |
+
return;
|
7025 |
+
}
|
7026 |
+
if (this.notifyPlugins('beforeDraw', {cancelable: true}) === false) {
|
7027 |
+
return;
|
7028 |
+
}
|
7029 |
+
const layers = this._layers;
|
7030 |
+
for (i = 0; i < layers.length && layers[i].z <= 0; ++i) {
|
7031 |
+
layers[i].draw(this.chartArea);
|
7032 |
+
}
|
7033 |
+
this._drawDatasets();
|
7034 |
+
for (; i < layers.length; ++i) {
|
7035 |
+
layers[i].draw(this.chartArea);
|
7036 |
+
}
|
7037 |
+
this.notifyPlugins('afterDraw');
|
7038 |
+
}
|
7039 |
+
_getSortedDatasetMetas(filterVisible) {
|
7040 |
+
const metasets = this._sortedMetasets;
|
7041 |
+
const result = [];
|
7042 |
+
let i, ilen;
|
7043 |
+
for (i = 0, ilen = metasets.length; i < ilen; ++i) {
|
7044 |
+
const meta = metasets[i];
|
7045 |
+
if (!filterVisible || meta.visible) {
|
7046 |
+
result.push(meta);
|
7047 |
+
}
|
7048 |
+
}
|
7049 |
+
return result;
|
7050 |
+
}
|
7051 |
+
getSortedVisibleDatasetMetas() {
|
7052 |
+
return this._getSortedDatasetMetas(true);
|
7053 |
+
}
|
7054 |
+
_drawDatasets() {
|
7055 |
+
if (this.notifyPlugins('beforeDatasetsDraw', {cancelable: true}) === false) {
|
7056 |
+
return;
|
7057 |
+
}
|
7058 |
+
const metasets = this.getSortedVisibleDatasetMetas();
|
7059 |
+
for (let i = metasets.length - 1; i >= 0; --i) {
|
7060 |
+
this._drawDataset(metasets[i]);
|
7061 |
+
}
|
7062 |
+
this.notifyPlugins('afterDatasetsDraw');
|
7063 |
+
}
|
7064 |
+
_drawDataset(meta) {
|
7065 |
+
const ctx = this.ctx;
|
7066 |
+
const clip = meta._clip;
|
7067 |
+
const useClip = !clip.disabled;
|
7068 |
+
const area = this.chartArea;
|
7069 |
+
const args = {
|
7070 |
+
meta,
|
7071 |
+
index: meta.index,
|
7072 |
+
cancelable: true
|
7073 |
+
};
|
7074 |
+
if (this.notifyPlugins('beforeDatasetDraw', args) === false) {
|
7075 |
+
return;
|
7076 |
+
}
|
7077 |
+
if (useClip) {
|
7078 |
+
clipArea(ctx, {
|
7079 |
+
left: clip.left === false ? 0 : area.left - clip.left,
|
7080 |
+
right: clip.right === false ? this.width : area.right + clip.right,
|
7081 |
+
top: clip.top === false ? 0 : area.top - clip.top,
|
7082 |
+
bottom: clip.bottom === false ? this.height : area.bottom + clip.bottom
|
7083 |
+
});
|
7084 |
+
}
|
7085 |
+
meta.controller.draw();
|
7086 |
+
if (useClip) {
|
7087 |
+
unclipArea(ctx);
|
7088 |
+
}
|
7089 |
+
args.cancelable = false;
|
7090 |
+
this.notifyPlugins('afterDatasetDraw', args);
|
7091 |
+
}
|
7092 |
+
getElementsAtEventForMode(e, mode, options, useFinalPosition) {
|
7093 |
+
const method = Interaction.modes[mode];
|
7094 |
+
if (typeof method === 'function') {
|
7095 |
+
return method(this, e, options, useFinalPosition);
|
7096 |
+
}
|
7097 |
+
return [];
|
7098 |
+
}
|
7099 |
+
getDatasetMeta(datasetIndex) {
|
7100 |
+
const dataset = this.data.datasets[datasetIndex];
|
7101 |
+
const metasets = this._metasets;
|
7102 |
+
let meta = metasets.filter(x => x && x._dataset === dataset).pop();
|
7103 |
+
if (!meta) {
|
7104 |
+
meta = {
|
7105 |
+
type: null,
|
7106 |
+
data: [],
|
7107 |
+
dataset: null,
|
7108 |
+
controller: null,
|
7109 |
+
hidden: null,
|
7110 |
+
xAxisID: null,
|
7111 |
+
yAxisID: null,
|
7112 |
+
order: dataset && dataset.order || 0,
|
7113 |
+
index: datasetIndex,
|
7114 |
+
_dataset: dataset,
|
7115 |
+
_parsed: [],
|
7116 |
+
_sorted: false
|
7117 |
+
};
|
7118 |
+
metasets.push(meta);
|
7119 |
+
}
|
7120 |
+
return meta;
|
7121 |
+
}
|
7122 |
+
getContext() {
|
7123 |
+
return this.$context || (this.$context = createContext(null, {chart: this, type: 'chart'}));
|
7124 |
+
}
|
7125 |
+
getVisibleDatasetCount() {
|
7126 |
+
return this.getSortedVisibleDatasetMetas().length;
|
7127 |
+
}
|
7128 |
+
isDatasetVisible(datasetIndex) {
|
7129 |
+
const dataset = this.data.datasets[datasetIndex];
|
7130 |
+
if (!dataset) {
|
7131 |
+
return false;
|
7132 |
+
}
|
7133 |
+
const meta = this.getDatasetMeta(datasetIndex);
|
7134 |
+
return typeof meta.hidden === 'boolean' ? !meta.hidden : !dataset.hidden;
|
7135 |
+
}
|
7136 |
+
setDatasetVisibility(datasetIndex, visible) {
|
7137 |
+
const meta = this.getDatasetMeta(datasetIndex);
|
7138 |
+
meta.hidden = !visible;
|
7139 |
+
}
|
7140 |
+
toggleDataVisibility(index) {
|
7141 |
+
this._hiddenIndices[index] = !this._hiddenIndices[index];
|
7142 |
+
}
|
7143 |
+
getDataVisibility(index) {
|
7144 |
+
return !this._hiddenIndices[index];
|
7145 |
+
}
|
7146 |
+
_updateVisibility(datasetIndex, dataIndex, visible) {
|
7147 |
+
const mode = visible ? 'show' : 'hide';
|
7148 |
+
const meta = this.getDatasetMeta(datasetIndex);
|
7149 |
+
const anims = meta.controller._resolveAnimations(undefined, mode);
|
7150 |
+
if (defined(dataIndex)) {
|
7151 |
+
meta.data[dataIndex].hidden = !visible;
|
7152 |
+
this.update();
|
7153 |
+
} else {
|
7154 |
+
this.setDatasetVisibility(datasetIndex, visible);
|
7155 |
+
anims.update(meta, {visible});
|
7156 |
+
this.update((ctx) => ctx.datasetIndex === datasetIndex ? mode : undefined);
|
7157 |
+
}
|
7158 |
+
}
|
7159 |
+
hide(datasetIndex, dataIndex) {
|
7160 |
+
this._updateVisibility(datasetIndex, dataIndex, false);
|
7161 |
+
}
|
7162 |
+
show(datasetIndex, dataIndex) {
|
7163 |
+
this._updateVisibility(datasetIndex, dataIndex, true);
|
7164 |
+
}
|
7165 |
+
_destroyDatasetMeta(datasetIndex) {
|
7166 |
+
const meta = this._metasets[datasetIndex];
|
7167 |
+
if (meta && meta.controller) {
|
7168 |
+
meta.controller._destroy();
|
7169 |
+
}
|
7170 |
+
delete this._metasets[datasetIndex];
|
7171 |
+
}
|
7172 |
+
_stop() {
|
7173 |
+
let i, ilen;
|
7174 |
+
this.stop();
|
7175 |
+
animator.remove(this);
|
7176 |
+
for (i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
|
7177 |
+
this._destroyDatasetMeta(i);
|
7178 |
+
}
|
7179 |
+
}
|
7180 |
+
destroy() {
|
7181 |
+
this.notifyPlugins('beforeDestroy');
|
7182 |
+
const {canvas, ctx} = this;
|
7183 |
+
this._stop();
|
7184 |
+
this.config.clearCache();
|
7185 |
+
if (canvas) {
|
7186 |
+
this.unbindEvents();
|
7187 |
+
clearCanvas(canvas, ctx);
|
7188 |
+
this.platform.releaseContext(ctx);
|
7189 |
+
this.canvas = null;
|
7190 |
+
this.ctx = null;
|
7191 |
+
}
|
7192 |
+
this.notifyPlugins('destroy');
|
7193 |
+
delete instances[this.id];
|
7194 |
+
this.notifyPlugins('afterDestroy');
|
7195 |
+
}
|
7196 |
+
toBase64Image(...args) {
|
7197 |
+
return this.canvas.toDataURL(...args);
|
7198 |
+
}
|
7199 |
+
bindEvents() {
|
7200 |
+
this.bindUserEvents();
|
7201 |
+
if (this.options.responsive) {
|
7202 |
+
this.bindResponsiveEvents();
|
7203 |
+
} else {
|
7204 |
+
this.attached = true;
|
7205 |
+
}
|
7206 |
+
}
|
7207 |
+
bindUserEvents() {
|
7208 |
+
const listeners = this._listeners;
|
7209 |
+
const platform = this.platform;
|
7210 |
+
const _add = (type, listener) => {
|
7211 |
+
platform.addEventListener(this, type, listener);
|
7212 |
+
listeners[type] = listener;
|
7213 |
+
};
|
7214 |
+
const listener = (e, x, y) => {
|
7215 |
+
e.offsetX = x;
|
7216 |
+
e.offsetY = y;
|
7217 |
+
this._eventHandler(e);
|
7218 |
+
};
|
7219 |
+
each(this.options.events, (type) => _add(type, listener));
|
7220 |
+
}
|
7221 |
+
bindResponsiveEvents() {
|
7222 |
+
if (!this._responsiveListeners) {
|
7223 |
+
this._responsiveListeners = {};
|
7224 |
+
}
|
7225 |
+
const listeners = this._responsiveListeners;
|
7226 |
+
const platform = this.platform;
|
7227 |
+
const _add = (type, listener) => {
|
7228 |
+
platform.addEventListener(this, type, listener);
|
7229 |
+
listeners[type] = listener;
|
7230 |
+
};
|
7231 |
+
const _remove = (type, listener) => {
|
7232 |
+
if (listeners[type]) {
|
7233 |
+
platform.removeEventListener(this, type, listener);
|
7234 |
+
delete listeners[type];
|
7235 |
+
}
|
7236 |
+
};
|
7237 |
+
const listener = (width, height) => {
|
7238 |
+
if (this.canvas) {
|
7239 |
+
this.resize(width, height);
|
7240 |
+
}
|
7241 |
+
};
|
7242 |
+
let detached;
|
7243 |
+
const attached = () => {
|
7244 |
+
_remove('attach', attached);
|
7245 |
+
this.attached = true;
|
7246 |
+
this.resize();
|
7247 |
+
_add('resize', listener);
|
7248 |
+
_add('detach', detached);
|
7249 |
+
};
|
7250 |
+
detached = () => {
|
7251 |
+
this.attached = false;
|
7252 |
+
_remove('resize', listener);
|
7253 |
+
this._stop();
|
7254 |
+
this._resize(0, 0);
|
7255 |
+
_add('attach', attached);
|
7256 |
+
};
|
7257 |
+
if (platform.isAttached(this.canvas)) {
|
7258 |
+
attached();
|
7259 |
+
} else {
|
7260 |
+
detached();
|
7261 |
+
}
|
7262 |
+
}
|
7263 |
+
unbindEvents() {
|
7264 |
+
each(this._listeners, (listener, type) => {
|
7265 |
+
this.platform.removeEventListener(this, type, listener);
|
7266 |
+
});
|
7267 |
+
this._listeners = {};
|
7268 |
+
each(this._responsiveListeners, (listener, type) => {
|
7269 |
+
this.platform.removeEventListener(this, type, listener);
|
7270 |
+
});
|
7271 |
+
this._responsiveListeners = undefined;
|
7272 |
+
}
|
7273 |
+
updateHoverStyle(items, mode, enabled) {
|
7274 |
+
const prefix = enabled ? 'set' : 'remove';
|
7275 |
+
let meta, item, i, ilen;
|
7276 |
+
if (mode === 'dataset') {
|
7277 |
+
meta = this.getDatasetMeta(items[0].datasetIndex);
|
7278 |
+
meta.controller['_' + prefix + 'DatasetHoverStyle']();
|
7279 |
+
}
|
7280 |
+
for (i = 0, ilen = items.length; i < ilen; ++i) {
|
7281 |
+
item = items[i];
|
7282 |
+
const controller = item && this.getDatasetMeta(item.datasetIndex).controller;
|
7283 |
+
if (controller) {
|
7284 |
+
controller[prefix + 'HoverStyle'](item.element, item.datasetIndex, item.index);
|
7285 |
+
}
|
7286 |
+
}
|
7287 |
+
}
|
7288 |
+
getActiveElements() {
|
7289 |
+
return this._active || [];
|
7290 |
+
}
|
7291 |
+
setActiveElements(activeElements) {
|
7292 |
+
const lastActive = this._active || [];
|
7293 |
+
const active = activeElements.map(({datasetIndex, index}) => {
|
7294 |
+
const meta = this.getDatasetMeta(datasetIndex);
|
7295 |
+
if (!meta) {
|
7296 |
+
throw new Error('No dataset found at index ' + datasetIndex);
|
7297 |
+
}
|
7298 |
+
return {
|
7299 |
+
datasetIndex,
|
7300 |
+
element: meta.data[index],
|
7301 |
+
index,
|
7302 |
+
};
|
7303 |
+
});
|
7304 |
+
const changed = !_elementsEqual(active, lastActive);
|
7305 |
+
if (changed) {
|
7306 |
+
this._active = active;
|
7307 |
+
this._lastEvent = null;
|
7308 |
+
this._updateHoverStyles(active, lastActive);
|
7309 |
+
}
|
7310 |
+
}
|
7311 |
+
notifyPlugins(hook, args, filter) {
|
7312 |
+
return this._plugins.notify(this, hook, args, filter);
|
7313 |
+
}
|
7314 |
+
_updateHoverStyles(active, lastActive, replay) {
|
7315 |
+
const hoverOptions = this.options.hover;
|
7316 |
+
const diff = (a, b) => a.filter(x => !b.some(y => x.datasetIndex === y.datasetIndex && x.index === y.index));
|
7317 |
+
const deactivated = diff(lastActive, active);
|
7318 |
+
const activated = replay ? active : diff(active, lastActive);
|
7319 |
+
if (deactivated.length) {
|
7320 |
+
this.updateHoverStyle(deactivated, hoverOptions.mode, false);
|
7321 |
+
}
|
7322 |
+
if (activated.length && hoverOptions.mode) {
|
7323 |
+
this.updateHoverStyle(activated, hoverOptions.mode, true);
|
7324 |
+
}
|
7325 |
+
}
|
7326 |
+
_eventHandler(e, replay) {
|
7327 |
+
const args = {
|
7328 |
+
event: e,
|
7329 |
+
replay,
|
7330 |
+
cancelable: true,
|
7331 |
+
inChartArea: _isPointInArea(e, this.chartArea, this._minPadding)
|
7332 |
+
};
|
7333 |
+
const eventFilter = (plugin) => (plugin.options.events || this.options.events).includes(e.native.type);
|
7334 |
+
if (this.notifyPlugins('beforeEvent', args, eventFilter) === false) {
|
7335 |
+
return;
|
7336 |
+
}
|
7337 |
+
const changed = this._handleEvent(e, replay, args.inChartArea);
|
7338 |
+
args.cancelable = false;
|
7339 |
+
this.notifyPlugins('afterEvent', args, eventFilter);
|
7340 |
+
if (changed || args.changed) {
|
7341 |
+
this.render();
|
7342 |
+
}
|
7343 |
+
return this;
|
7344 |
+
}
|
7345 |
+
_handleEvent(e, replay, inChartArea) {
|
7346 |
+
const {_active: lastActive = [], options} = this;
|
7347 |
+
const useFinalPosition = replay;
|
7348 |
+
const active = this._getActiveElements(e, lastActive, inChartArea, useFinalPosition);
|
7349 |
+
const isClick = _isClickEvent(e);
|
7350 |
+
const lastEvent = determineLastEvent(e, this._lastEvent, inChartArea, isClick);
|
7351 |
+
if (inChartArea) {
|
7352 |
+
this._lastEvent = null;
|
7353 |
+
callback(options.onHover, [e, active, this], this);
|
7354 |
+
if (isClick) {
|
7355 |
+
callback(options.onClick, [e, active, this], this);
|
7356 |
+
}
|
7357 |
+
}
|
7358 |
+
const changed = !_elementsEqual(active, lastActive);
|
7359 |
+
if (changed || replay) {
|
7360 |
+
this._active = active;
|
7361 |
+
this._updateHoverStyles(active, lastActive, replay);
|
7362 |
+
}
|
7363 |
+
this._lastEvent = lastEvent;
|
7364 |
+
return changed;
|
7365 |
+
}
|
7366 |
+
_getActiveElements(e, lastActive, inChartArea, useFinalPosition) {
|
7367 |
+
if (e.type === 'mouseout') {
|
7368 |
+
return [];
|
7369 |
+
}
|
7370 |
+
if (!inChartArea) {
|
7371 |
+
return lastActive;
|
7372 |
+
}
|
7373 |
+
const hoverOptions = this.options.hover;
|
7374 |
+
return this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition);
|
7375 |
+
}
|
7376 |
+
}
|
7377 |
+
const invalidatePlugins = () => each(Chart.instances, (chart) => chart._plugins.invalidate());
|
7378 |
+
const enumerable = true;
|
7379 |
+
Object.defineProperties(Chart, {
|
7380 |
+
defaults: {
|
7381 |
+
enumerable,
|
7382 |
+
value: defaults
|
7383 |
+
},
|
7384 |
+
instances: {
|
7385 |
+
enumerable,
|
7386 |
+
value: instances
|
7387 |
+
},
|
7388 |
+
overrides: {
|
7389 |
+
enumerable,
|
7390 |
+
value: overrides
|
7391 |
+
},
|
7392 |
+
registry: {
|
7393 |
+
enumerable,
|
7394 |
+
value: registry
|
7395 |
+
},
|
7396 |
+
version: {
|
7397 |
+
enumerable,
|
7398 |
+
value: version
|
7399 |
+
},
|
7400 |
+
getChart: {
|
7401 |
+
enumerable,
|
7402 |
+
value: getChart
|
7403 |
+
},
|
7404 |
+
register: {
|
7405 |
+
enumerable,
|
7406 |
+
value: (...items) => {
|
7407 |
+
registry.add(...items);
|
7408 |
+
invalidatePlugins();
|
7409 |
+
}
|
7410 |
+
},
|
7411 |
+
unregister: {
|
7412 |
+
enumerable,
|
7413 |
+
value: (...items) => {
|
7414 |
+
registry.remove(...items);
|
7415 |
+
invalidatePlugins();
|
7416 |
+
}
|
7417 |
+
}
|
7418 |
+
});
|
7419 |
+
|
7420 |
+
function abstract() {
|
7421 |
+
throw new Error('This method is not implemented: Check that a complete date adapter is provided.');
|
7422 |
+
}
|
7423 |
+
class DateAdapter {
|
7424 |
+
constructor(options) {
|
7425 |
+
this.options = options || {};
|
7426 |
+
}
|
7427 |
+
formats() {
|
7428 |
+
return abstract();
|
7429 |
+
}
|
7430 |
+
parse(value, format) {
|
7431 |
+
return abstract();
|
7432 |
+
}
|
7433 |
+
format(timestamp, format) {
|
7434 |
+
return abstract();
|
7435 |
+
}
|
7436 |
+
add(timestamp, amount, unit) {
|
7437 |
+
return abstract();
|
7438 |
+
}
|
7439 |
+
diff(a, b, unit) {
|
7440 |
+
return abstract();
|
7441 |
+
}
|
7442 |
+
startOf(timestamp, unit, weekday) {
|
7443 |
+
return abstract();
|
7444 |
+
}
|
7445 |
+
endOf(timestamp, unit) {
|
7446 |
+
return abstract();
|
7447 |
+
}
|
7448 |
+
}
|
7449 |
+
DateAdapter.override = function(members) {
|
7450 |
+
Object.assign(DateAdapter.prototype, members);
|
7451 |
+
};
|
7452 |
+
var _adapters = {
|
7453 |
+
_date: DateAdapter
|
7454 |
+
};
|
7455 |
+
|
7456 |
+
function getAllScaleValues(scale, type) {
|
7457 |
+
if (!scale._cache.$bar) {
|
7458 |
+
const visibleMetas = scale.getMatchingVisibleMetas(type);
|
7459 |
+
let values = [];
|
7460 |
+
for (let i = 0, ilen = visibleMetas.length; i < ilen; i++) {
|
7461 |
+
values = values.concat(visibleMetas[i].controller.getAllParsedValues(scale));
|
7462 |
+
}
|
7463 |
+
scale._cache.$bar = _arrayUnique(values.sort((a, b) => a - b));
|
7464 |
+
}
|
7465 |
+
return scale._cache.$bar;
|
7466 |
+
}
|
7467 |
+
function computeMinSampleSize(meta) {
|
7468 |
+
const scale = meta.iScale;
|
7469 |
+
const values = getAllScaleValues(scale, meta.type);
|
7470 |
+
let min = scale._length;
|
7471 |
+
let i, ilen, curr, prev;
|
7472 |
+
const updateMinAndPrev = () => {
|
7473 |
+
if (curr === 32767 || curr === -32768) {
|
7474 |
+
return;
|
7475 |
+
}
|
7476 |
+
if (defined(prev)) {
|
7477 |
+
min = Math.min(min, Math.abs(curr - prev) || min);
|
7478 |
+
}
|
7479 |
+
prev = curr;
|
7480 |
+
};
|
7481 |
+
for (i = 0, ilen = values.length; i < ilen; ++i) {
|
7482 |
+
curr = scale.getPixelForValue(values[i]);
|
7483 |
+
updateMinAndPrev();
|
7484 |
+
}
|
7485 |
+
prev = undefined;
|
7486 |
+
for (i = 0, ilen = scale.ticks.length; i < ilen; ++i) {
|
7487 |
+
curr = scale.getPixelForTick(i);
|
7488 |
+
updateMinAndPrev();
|
7489 |
+
}
|
7490 |
+
return min;
|
7491 |
+
}
|
7492 |
+
function computeFitCategoryTraits(index, ruler, options, stackCount) {
|
7493 |
+
const thickness = options.barThickness;
|
7494 |
+
let size, ratio;
|
7495 |
+
if (isNullOrUndef(thickness)) {
|
7496 |
+
size = ruler.min * options.categoryPercentage;
|
7497 |
+
ratio = options.barPercentage;
|
7498 |
+
} else {
|
7499 |
+
size = thickness * stackCount;
|
7500 |
+
ratio = 1;
|
7501 |
+
}
|
7502 |
+
return {
|
7503 |
+
chunk: size / stackCount,
|
7504 |
+
ratio,
|
7505 |
+
start: ruler.pixels[index] - (size / 2)
|
7506 |
+
};
|
7507 |
+
}
|
7508 |
+
function computeFlexCategoryTraits(index, ruler, options, stackCount) {
|
7509 |
+
const pixels = ruler.pixels;
|
7510 |
+
const curr = pixels[index];
|
7511 |
+
let prev = index > 0 ? pixels[index - 1] : null;
|
7512 |
+
let next = index < pixels.length - 1 ? pixels[index + 1] : null;
|
7513 |
+
const percent = options.categoryPercentage;
|
7514 |
+
if (prev === null) {
|
7515 |
+
prev = curr - (next === null ? ruler.end - ruler.start : next - curr);
|
7516 |
+
}
|
7517 |
+
if (next === null) {
|
7518 |
+
next = curr + curr - prev;
|
7519 |
+
}
|
7520 |
+
const start = curr - (curr - Math.min(prev, next)) / 2 * percent;
|
7521 |
+
const size = Math.abs(next - prev) / 2 * percent;
|
7522 |
+
return {
|
7523 |
+
chunk: size / stackCount,
|
7524 |
+
ratio: options.barPercentage,
|
7525 |
+
start
|
7526 |
+
};
|
7527 |
+
}
|
7528 |
+
function parseFloatBar(entry, item, vScale, i) {
|
7529 |
+
const startValue = vScale.parse(entry[0], i);
|
7530 |
+
const endValue = vScale.parse(entry[1], i);
|
7531 |
+
const min = Math.min(startValue, endValue);
|
7532 |
+
const max = Math.max(startValue, endValue);
|
7533 |
+
let barStart = min;
|
7534 |
+
let barEnd = max;
|
7535 |
+
if (Math.abs(min) > Math.abs(max)) {
|
7536 |
+
barStart = max;
|
7537 |
+
barEnd = min;
|
7538 |
+
}
|
7539 |
+
item[vScale.axis] = barEnd;
|
7540 |
+
item._custom = {
|
7541 |
+
barStart,
|
7542 |
+
barEnd,
|
7543 |
+
start: startValue,
|
7544 |
+
end: endValue,
|
7545 |
+
min,
|
7546 |
+
max
|
7547 |
+
};
|
7548 |
+
}
|
7549 |
+
function parseValue(entry, item, vScale, i) {
|
7550 |
+
if (isArray(entry)) {
|
7551 |
+
parseFloatBar(entry, item, vScale, i);
|
7552 |
+
} else {
|
7553 |
+
item[vScale.axis] = vScale.parse(entry, i);
|
7554 |
+
}
|
7555 |
+
return item;
|
7556 |
+
}
|
7557 |
+
function parseArrayOrPrimitive(meta, data, start, count) {
|
7558 |
+
const iScale = meta.iScale;
|
7559 |
+
const vScale = meta.vScale;
|
7560 |
+
const labels = iScale.getLabels();
|
7561 |
+
const singleScale = iScale === vScale;
|
7562 |
+
const parsed = [];
|
7563 |
+
let i, ilen, item, entry;
|
7564 |
+
for (i = start, ilen = start + count; i < ilen; ++i) {
|
7565 |
+
entry = data[i];
|
7566 |
+
item = {};
|
7567 |
+
item[iScale.axis] = singleScale || iScale.parse(labels[i], i);
|
7568 |
+
parsed.push(parseValue(entry, item, vScale, i));
|
7569 |
+
}
|
7570 |
+
return parsed;
|
7571 |
+
}
|
7572 |
+
function isFloatBar(custom) {
|
7573 |
+
return custom && custom.barStart !== undefined && custom.barEnd !== undefined;
|
7574 |
+
}
|
7575 |
+
function barSign(size, vScale, actualBase) {
|
7576 |
+
if (size !== 0) {
|
7577 |
+
return sign(size);
|
7578 |
+
}
|
7579 |
+
return (vScale.isHorizontal() ? 1 : -1) * (vScale.min >= actualBase ? 1 : -1);
|
7580 |
+
}
|
7581 |
+
function borderProps(properties) {
|
7582 |
+
let reverse, start, end, top, bottom;
|
7583 |
+
if (properties.horizontal) {
|
7584 |
+
reverse = properties.base > properties.x;
|
7585 |
+
start = 'left';
|
7586 |
+
end = 'right';
|
7587 |
+
} else {
|
7588 |
+
reverse = properties.base < properties.y;
|
7589 |
+
start = 'bottom';
|
7590 |
+
end = 'top';
|
7591 |
+
}
|
7592 |
+
if (reverse) {
|
7593 |
+
top = 'end';
|
7594 |
+
bottom = 'start';
|
7595 |
+
} else {
|
7596 |
+
top = 'start';
|
7597 |
+
bottom = 'end';
|
7598 |
+
}
|
7599 |
+
return {start, end, reverse, top, bottom};
|
7600 |
+
}
|
7601 |
+
function setBorderSkipped(properties, options, stack, index) {
|
7602 |
+
let edge = options.borderSkipped;
|
7603 |
+
const res = {};
|
7604 |
+
if (!edge) {
|
7605 |
+
properties.borderSkipped = res;
|
7606 |
+
return;
|
7607 |
+
}
|
7608 |
+
const {start, end, reverse, top, bottom} = borderProps(properties);
|
7609 |
+
if (edge === 'middle' && stack) {
|
7610 |
+
properties.enableBorderRadius = true;
|
7611 |
+
if ((stack._top || 0) === index) {
|
7612 |
+
edge = top;
|
7613 |
+
} else if ((stack._bottom || 0) === index) {
|
7614 |
+
edge = bottom;
|
7615 |
+
} else {
|
7616 |
+
res[parseEdge(bottom, start, end, reverse)] = true;
|
7617 |
+
edge = top;
|
7618 |
+
}
|
7619 |
+
}
|
7620 |
+
res[parseEdge(edge, start, end, reverse)] = true;
|
7621 |
+
properties.borderSkipped = res;
|
7622 |
+
}
|
7623 |
+
function parseEdge(edge, a, b, reverse) {
|
7624 |
+
if (reverse) {
|
7625 |
+
edge = swap(edge, a, b);
|
7626 |
+
edge = startEnd(edge, b, a);
|
7627 |
+
} else {
|
7628 |
+
edge = startEnd(edge, a, b);
|
7629 |
+
}
|
7630 |
+
return edge;
|
7631 |
+
}
|
7632 |
+
function swap(orig, v1, v2) {
|
7633 |
+
return orig === v1 ? v2 : orig === v2 ? v1 : orig;
|
7634 |
+
}
|
7635 |
+
function startEnd(v, start, end) {
|
7636 |
+
return v === 'start' ? start : v === 'end' ? end : v;
|
7637 |
+
}
|
7638 |
+
function setInflateAmount(properties, {inflateAmount}, ratio) {
|
7639 |
+
properties.inflateAmount = inflateAmount === 'auto'
|
7640 |
+
? ratio === 1 ? 0.33 : 0
|
7641 |
+
: inflateAmount;
|
7642 |
+
}
|
7643 |
+
class BarController extends DatasetController {
|
7644 |
+
parsePrimitiveData(meta, data, start, count) {
|
7645 |
+
return parseArrayOrPrimitive(meta, data, start, count);
|
7646 |
+
}
|
7647 |
+
parseArrayData(meta, data, start, count) {
|
7648 |
+
return parseArrayOrPrimitive(meta, data, start, count);
|
7649 |
+
}
|
7650 |
+
parseObjectData(meta, data, start, count) {
|
7651 |
+
const {iScale, vScale} = meta;
|
7652 |
+
const {xAxisKey = 'x', yAxisKey = 'y'} = this._parsing;
|
7653 |
+
const iAxisKey = iScale.axis === 'x' ? xAxisKey : yAxisKey;
|
7654 |
+
const vAxisKey = vScale.axis === 'x' ? xAxisKey : yAxisKey;
|
7655 |
+
const parsed = [];
|
7656 |
+
let i, ilen, item, obj;
|
7657 |
+
for (i = start, ilen = start + count; i < ilen; ++i) {
|
7658 |
+
obj = data[i];
|
7659 |
+
item = {};
|
7660 |
+
item[iScale.axis] = iScale.parse(resolveObjectKey(obj, iAxisKey), i);
|
7661 |
+
parsed.push(parseValue(resolveObjectKey(obj, vAxisKey), item, vScale, i));
|
7662 |
+
}
|
7663 |
+
return parsed;
|
7664 |
+
}
|
7665 |
+
updateRangeFromParsed(range, scale, parsed, stack) {
|
7666 |
+
super.updateRangeFromParsed(range, scale, parsed, stack);
|
7667 |
+
const custom = parsed._custom;
|
7668 |
+
if (custom && scale === this._cachedMeta.vScale) {
|
7669 |
+
range.min = Math.min(range.min, custom.min);
|
7670 |
+
range.max = Math.max(range.max, custom.max);
|
7671 |
+
}
|
7672 |
+
}
|
7673 |
+
getMaxOverflow() {
|
7674 |
+
return 0;
|
7675 |
+
}
|
7676 |
+
getLabelAndValue(index) {
|
7677 |
+
const meta = this._cachedMeta;
|
7678 |
+
const {iScale, vScale} = meta;
|
7679 |
+
const parsed = this.getParsed(index);
|
7680 |
+
const custom = parsed._custom;
|
7681 |
+
const value = isFloatBar(custom)
|
7682 |
+
? '[' + custom.start + ', ' + custom.end + ']'
|
7683 |
+
: '' + vScale.getLabelForValue(parsed[vScale.axis]);
|
7684 |
+
return {
|
7685 |
+
label: '' + iScale.getLabelForValue(parsed[iScale.axis]),
|
7686 |
+
value
|
7687 |
+
};
|
7688 |
+
}
|
7689 |
+
initialize() {
|
7690 |
+
this.enableOptionSharing = true;
|
7691 |
+
super.initialize();
|
7692 |
+
const meta = this._cachedMeta;
|
7693 |
+
meta.stack = this.getDataset().stack;
|
7694 |
+
}
|
7695 |
+
update(mode) {
|
7696 |
+
const meta = this._cachedMeta;
|
7697 |
+
this.updateElements(meta.data, 0, meta.data.length, mode);
|
7698 |
+
}
|
7699 |
+
updateElements(bars, start, count, mode) {
|
7700 |
+
const reset = mode === 'reset';
|
7701 |
+
const {index, _cachedMeta: {vScale}} = this;
|
7702 |
+
const base = vScale.getBasePixel();
|
7703 |
+
const horizontal = vScale.isHorizontal();
|
7704 |
+
const ruler = this._getRuler();
|
7705 |
+
const firstOpts = this.resolveDataElementOptions(start, mode);
|
7706 |
+
const sharedOptions = this.getSharedOptions(firstOpts);
|
7707 |
+
const includeOptions = this.includeOptions(mode, sharedOptions);
|
7708 |
+
this.updateSharedOptions(sharedOptions, mode, firstOpts);
|
7709 |
+
for (let i = start; i < start + count; i++) {
|
7710 |
+
const parsed = this.getParsed(i);
|
7711 |
+
const vpixels = reset || isNullOrUndef(parsed[vScale.axis]) ? {base, head: base} : this._calculateBarValuePixels(i);
|
7712 |
+
const ipixels = this._calculateBarIndexPixels(i, ruler);
|
7713 |
+
const stack = (parsed._stacks || {})[vScale.axis];
|
7714 |
+
const properties = {
|
7715 |
+
horizontal,
|
7716 |
+
base: vpixels.base,
|
7717 |
+
enableBorderRadius: !stack || isFloatBar(parsed._custom) || (index === stack._top || index === stack._bottom),
|
7718 |
+
x: horizontal ? vpixels.head : ipixels.center,
|
7719 |
+
y: horizontal ? ipixels.center : vpixels.head,
|
7720 |
+
height: horizontal ? ipixels.size : Math.abs(vpixels.size),
|
7721 |
+
width: horizontal ? Math.abs(vpixels.size) : ipixels.size
|
7722 |
+
};
|
7723 |
+
if (includeOptions) {
|
7724 |
+
properties.options = sharedOptions || this.resolveDataElementOptions(i, bars[i].active ? 'active' : mode);
|
7725 |
+
}
|
7726 |
+
const options = properties.options || bars[i].options;
|
7727 |
+
setBorderSkipped(properties, options, stack, index);
|
7728 |
+
setInflateAmount(properties, options, ruler.ratio);
|
7729 |
+
this.updateElement(bars[i], i, properties, mode);
|
7730 |
+
}
|
7731 |
+
}
|
7732 |
+
_getStacks(last, dataIndex) {
|
7733 |
+
const meta = this._cachedMeta;
|
7734 |
+
const iScale = meta.iScale;
|
7735 |
+
const metasets = iScale.getMatchingVisibleMetas(this._type);
|
7736 |
+
const stacked = iScale.options.stacked;
|
7737 |
+
const ilen = metasets.length;
|
7738 |
+
const stacks = [];
|
7739 |
+
let i, item;
|
7740 |
+
for (i = 0; i < ilen; ++i) {
|
7741 |
+
item = metasets[i];
|
7742 |
+
if (!item.controller.options.grouped) {
|
7743 |
+
continue;
|
7744 |
+
}
|
7745 |
+
if (typeof dataIndex !== 'undefined') {
|
7746 |
+
const val = item.controller.getParsed(dataIndex)[
|
7747 |
+
item.controller._cachedMeta.vScale.axis
|
7748 |
+
];
|
7749 |
+
if (isNullOrUndef(val) || isNaN(val)) {
|
7750 |
+
continue;
|
7751 |
+
}
|
7752 |
+
}
|
7753 |
+
if (stacked === false || stacks.indexOf(item.stack) === -1 ||
|
7754 |
+
(stacked === undefined && item.stack === undefined)) {
|
7755 |
+
stacks.push(item.stack);
|
7756 |
+
}
|
7757 |
+
if (item.index === last) {
|
7758 |
+
break;
|
7759 |
+
}
|
7760 |
+
}
|
7761 |
+
if (!stacks.length) {
|
7762 |
+
stacks.push(undefined);
|
7763 |
+
}
|
7764 |
+
return stacks;
|
7765 |
+
}
|
7766 |
+
_getStackCount(index) {
|
7767 |
+
return this._getStacks(undefined, index).length;
|
7768 |
+
}
|
7769 |
+
_getStackIndex(datasetIndex, name, dataIndex) {
|
7770 |
+
const stacks = this._getStacks(datasetIndex, dataIndex);
|
7771 |
+
const index = (name !== undefined)
|
7772 |
+
? stacks.indexOf(name)
|
7773 |
+
: -1;
|
7774 |
+
return (index === -1)
|
7775 |
+
? stacks.length - 1
|
7776 |
+
: index;
|
7777 |
+
}
|
7778 |
+
_getRuler() {
|
7779 |
+
const opts = this.options;
|
7780 |
+
const meta = this._cachedMeta;
|
7781 |
+
const iScale = meta.iScale;
|
7782 |
+
const pixels = [];
|
7783 |
+
let i, ilen;
|
7784 |
+
for (i = 0, ilen = meta.data.length; i < ilen; ++i) {
|
7785 |
+
pixels.push(iScale.getPixelForValue(this.getParsed(i)[iScale.axis], i));
|
7786 |
+
}
|
7787 |
+
const barThickness = opts.barThickness;
|
7788 |
+
const min = barThickness || computeMinSampleSize(meta);
|
7789 |
+
return {
|
7790 |
+
min,
|
7791 |
+
pixels,
|
7792 |
+
start: iScale._startPixel,
|
7793 |
+
end: iScale._endPixel,
|
7794 |
+
stackCount: this._getStackCount(),
|
7795 |
+
scale: iScale,
|
7796 |
+
grouped: opts.grouped,
|
7797 |
+
ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage
|
7798 |
+
};
|
7799 |
+
}
|
7800 |
+
_calculateBarValuePixels(index) {
|
7801 |
+
const {_cachedMeta: {vScale, _stacked}, options: {base: baseValue, minBarLength}} = this;
|
7802 |
+
const actualBase = baseValue || 0;
|
7803 |
+
const parsed = this.getParsed(index);
|
7804 |
+
const custom = parsed._custom;
|
7805 |
+
const floating = isFloatBar(custom);
|
7806 |
+
let value = parsed[vScale.axis];
|
7807 |
+
let start = 0;
|
7808 |
+
let length = _stacked ? this.applyStack(vScale, parsed, _stacked) : value;
|
7809 |
+
let head, size;
|
7810 |
+
if (length !== value) {
|
7811 |
+
start = length - value;
|
7812 |
+
length = value;
|
7813 |
+
}
|
7814 |
+
if (floating) {
|
7815 |
+
value = custom.barStart;
|
7816 |
+
length = custom.barEnd - custom.barStart;
|
7817 |
+
if (value !== 0 && sign(value) !== sign(custom.barEnd)) {
|
7818 |
+
start = 0;
|
7819 |
+
}
|
7820 |
+
start += value;
|
7821 |
+
}
|
7822 |
+
const startValue = !isNullOrUndef(baseValue) && !floating ? baseValue : start;
|
7823 |
+
let base = vScale.getPixelForValue(startValue);
|
7824 |
+
if (this.chart.getDataVisibility(index)) {
|
7825 |
+
head = vScale.getPixelForValue(start + length);
|
7826 |
+
} else {
|
7827 |
+
head = base;
|
7828 |
+
}
|
7829 |
+
size = head - base;
|
7830 |
+
if (Math.abs(size) < minBarLength) {
|
7831 |
+
size = barSign(size, vScale, actualBase) * minBarLength;
|
7832 |
+
if (value === actualBase) {
|
7833 |
+
base -= size / 2;
|
7834 |
+
}
|
7835 |
+
head = base + size;
|
7836 |
+
}
|
7837 |
+
if (base === vScale.getPixelForValue(actualBase)) {
|
7838 |
+
const halfGrid = sign(size) * vScale.getLineWidthForValue(actualBase) / 2;
|
7839 |
+
base += halfGrid;
|
7840 |
+
size -= halfGrid;
|
7841 |
+
}
|
7842 |
+
return {
|
7843 |
+
size,
|
7844 |
+
base,
|
7845 |
+
head,
|
7846 |
+
center: head + size / 2
|
7847 |
+
};
|
7848 |
+
}
|
7849 |
+
_calculateBarIndexPixels(index, ruler) {
|
7850 |
+
const scale = ruler.scale;
|
7851 |
+
const options = this.options;
|
7852 |
+
const skipNull = options.skipNull;
|
7853 |
+
const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity);
|
7854 |
+
let center, size;
|
7855 |
+
if (ruler.grouped) {
|
7856 |
+
const stackCount = skipNull ? this._getStackCount(index) : ruler.stackCount;
|
7857 |
+
const range = options.barThickness === 'flex'
|
7858 |
+
? computeFlexCategoryTraits(index, ruler, options, stackCount)
|
7859 |
+
: computeFitCategoryTraits(index, ruler, options, stackCount);
|
7860 |
+
const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined);
|
7861 |
+
center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
|
7862 |
+
size = Math.min(maxBarThickness, range.chunk * range.ratio);
|
7863 |
+
} else {
|
7864 |
+
center = scale.getPixelForValue(this.getParsed(index)[scale.axis], index);
|
7865 |
+
size = Math.min(maxBarThickness, ruler.min * ruler.ratio);
|
7866 |
+
}
|
7867 |
+
return {
|
7868 |
+
base: center - size / 2,
|
7869 |
+
head: center + size / 2,
|
7870 |
+
center,
|
7871 |
+
size
|
7872 |
+
};
|
7873 |
+
}
|
7874 |
+
draw() {
|
7875 |
+
const meta = this._cachedMeta;
|
7876 |
+
const vScale = meta.vScale;
|
7877 |
+
const rects = meta.data;
|
7878 |
+
const ilen = rects.length;
|
7879 |
+
let i = 0;
|
7880 |
+
for (; i < ilen; ++i) {
|
7881 |
+
if (this.getParsed(i)[vScale.axis] !== null) {
|
7882 |
+
rects[i].draw(this._ctx);
|
7883 |
+
}
|
7884 |
+
}
|
7885 |
+
}
|
7886 |
+
}
|
7887 |
+
BarController.id = 'bar';
|
7888 |
+
BarController.defaults = {
|
7889 |
+
datasetElementType: false,
|
7890 |
+
dataElementType: 'bar',
|
7891 |
+
categoryPercentage: 0.8,
|
7892 |
+
barPercentage: 0.9,
|
7893 |
+
grouped: true,
|
7894 |
+
animations: {
|
7895 |
+
numbers: {
|
7896 |
+
type: 'number',
|
7897 |
+
properties: ['x', 'y', 'base', 'width', 'height']
|
7898 |
+
}
|
7899 |
+
}
|
7900 |
+
};
|
7901 |
+
BarController.overrides = {
|
7902 |
+
scales: {
|
7903 |
+
_index_: {
|
7904 |
+
type: 'category',
|
7905 |
+
offset: true,
|
7906 |
+
grid: {
|
7907 |
+
offset: true
|
7908 |
+
}
|
7909 |
+
},
|
7910 |
+
_value_: {
|
7911 |
+
type: 'linear',
|
7912 |
+
beginAtZero: true,
|
7913 |
+
}
|
7914 |
+
}
|
7915 |
+
};
|
7916 |
+
|
7917 |
+
class BubbleController extends DatasetController {
|
7918 |
+
initialize() {
|
7919 |
+
this.enableOptionSharing = true;
|
7920 |
+
super.initialize();
|
7921 |
+
}
|
7922 |
+
parsePrimitiveData(meta, data, start, count) {
|
7923 |
+
const parsed = super.parsePrimitiveData(meta, data, start, count);
|
7924 |
+
for (let i = 0; i < parsed.length; i++) {
|
7925 |
+
parsed[i]._custom = this.resolveDataElementOptions(i + start).radius;
|
7926 |
+
}
|
7927 |
+
return parsed;
|
7928 |
+
}
|
7929 |
+
parseArrayData(meta, data, start, count) {
|
7930 |
+
const parsed = super.parseArrayData(meta, data, start, count);
|
7931 |
+
for (let i = 0; i < parsed.length; i++) {
|
7932 |
+
const item = data[start + i];
|
7933 |
+
parsed[i]._custom = valueOrDefault(item[2], this.resolveDataElementOptions(i + start).radius);
|
7934 |
+
}
|
7935 |
+
return parsed;
|
7936 |
+
}
|
7937 |
+
parseObjectData(meta, data, start, count) {
|
7938 |
+
const parsed = super.parseObjectData(meta, data, start, count);
|
7939 |
+
for (let i = 0; i < parsed.length; i++) {
|
7940 |
+
const item = data[start + i];
|
7941 |
+
parsed[i]._custom = valueOrDefault(item && item.r && +item.r, this.resolveDataElementOptions(i + start).radius);
|
7942 |
+
}
|
7943 |
+
return parsed;
|
7944 |
+
}
|
7945 |
+
getMaxOverflow() {
|
7946 |
+
const data = this._cachedMeta.data;
|
7947 |
+
let max = 0;
|
7948 |
+
for (let i = data.length - 1; i >= 0; --i) {
|
7949 |
+
max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2);
|
7950 |
+
}
|
7951 |
+
return max > 0 && max;
|
7952 |
+
}
|
7953 |
+
getLabelAndValue(index) {
|
7954 |
+
const meta = this._cachedMeta;
|
7955 |
+
const {xScale, yScale} = meta;
|
7956 |
+
const parsed = this.getParsed(index);
|
7957 |
+
const x = xScale.getLabelForValue(parsed.x);
|
7958 |
+
const y = yScale.getLabelForValue(parsed.y);
|
7959 |
+
const r = parsed._custom;
|
7960 |
+
return {
|
7961 |
+
label: meta.label,
|
7962 |
+
value: '(' + x + ', ' + y + (r ? ', ' + r : '') + ')'
|
7963 |
+
};
|
7964 |
+
}
|
7965 |
+
update(mode) {
|
7966 |
+
const points = this._cachedMeta.data;
|
7967 |
+
this.updateElements(points, 0, points.length, mode);
|
7968 |
+
}
|
7969 |
+
updateElements(points, start, count, mode) {
|
7970 |
+
const reset = mode === 'reset';
|
7971 |
+
const {iScale, vScale} = this._cachedMeta;
|
7972 |
+
const firstOpts = this.resolveDataElementOptions(start, mode);
|
7973 |
+
const sharedOptions = this.getSharedOptions(firstOpts);
|
7974 |
+
const includeOptions = this.includeOptions(mode, sharedOptions);
|
7975 |
+
const iAxis = iScale.axis;
|
7976 |
+
const vAxis = vScale.axis;
|
7977 |
+
for (let i = start; i < start + count; i++) {
|
7978 |
+
const point = points[i];
|
7979 |
+
const parsed = !reset && this.getParsed(i);
|
7980 |
+
const properties = {};
|
7981 |
+
const iPixel = properties[iAxis] = reset ? iScale.getPixelForDecimal(0.5) : iScale.getPixelForValue(parsed[iAxis]);
|
7982 |
+
const vPixel = properties[vAxis] = reset ? vScale.getBasePixel() : vScale.getPixelForValue(parsed[vAxis]);
|
7983 |
+
properties.skip = isNaN(iPixel) || isNaN(vPixel);
|
7984 |
+
if (includeOptions) {
|
7985 |
+
properties.options = this.resolveDataElementOptions(i, point.active ? 'active' : mode);
|
7986 |
+
if (reset) {
|
7987 |
+
properties.options.radius = 0;
|
7988 |
+
}
|
7989 |
+
}
|
7990 |
+
this.updateElement(point, i, properties, mode);
|
7991 |
+
}
|
7992 |
+
this.updateSharedOptions(sharedOptions, mode, firstOpts);
|
7993 |
+
}
|
7994 |
+
resolveDataElementOptions(index, mode) {
|
7995 |
+
const parsed = this.getParsed(index);
|
7996 |
+
let values = super.resolveDataElementOptions(index, mode);
|
7997 |
+
if (values.$shared) {
|
7998 |
+
values = Object.assign({}, values, {$shared: false});
|
7999 |
+
}
|
8000 |
+
const radius = values.radius;
|
8001 |
+
if (mode !== 'active') {
|
8002 |
+
values.radius = 0;
|
8003 |
+
}
|
8004 |
+
values.radius += valueOrDefault(parsed && parsed._custom, radius);
|
8005 |
+
return values;
|
8006 |
+
}
|
8007 |
+
}
|
8008 |
+
BubbleController.id = 'bubble';
|
8009 |
+
BubbleController.defaults = {
|
8010 |
+
datasetElementType: false,
|
8011 |
+
dataElementType: 'point',
|
8012 |
+
animations: {
|
8013 |
+
numbers: {
|
8014 |
+
type: 'number',
|
8015 |
+
properties: ['x', 'y', 'borderWidth', 'radius']
|
8016 |
+
}
|
8017 |
+
}
|
8018 |
+
};
|
8019 |
+
BubbleController.overrides = {
|
8020 |
+
scales: {
|
8021 |
+
x: {
|
8022 |
+
type: 'linear'
|
8023 |
+
},
|
8024 |
+
y: {
|
8025 |
+
type: 'linear'
|
8026 |
+
}
|
8027 |
+
},
|
8028 |
+
plugins: {
|
8029 |
+
tooltip: {
|
8030 |
+
callbacks: {
|
8031 |
+
title() {
|
8032 |
+
return '';
|
8033 |
+
}
|
8034 |
+
}
|
8035 |
+
}
|
8036 |
+
}
|
8037 |
+
};
|
8038 |
+
|
8039 |
+
function getRatioAndOffset(rotation, circumference, cutout) {
|
8040 |
+
let ratioX = 1;
|
8041 |
+
let ratioY = 1;
|
8042 |
+
let offsetX = 0;
|
8043 |
+
let offsetY = 0;
|
8044 |
+
if (circumference < TAU) {
|
8045 |
+
const startAngle = rotation;
|
8046 |
+
const endAngle = startAngle + circumference;
|
8047 |
+
const startX = Math.cos(startAngle);
|
8048 |
+
const startY = Math.sin(startAngle);
|
8049 |
+
const endX = Math.cos(endAngle);
|
8050 |
+
const endY = Math.sin(endAngle);
|
8051 |
+
const calcMax = (angle, a, b) => _angleBetween(angle, startAngle, endAngle, true) ? 1 : Math.max(a, a * cutout, b, b * cutout);
|
8052 |
+
const calcMin = (angle, a, b) => _angleBetween(angle, startAngle, endAngle, true) ? -1 : Math.min(a, a * cutout, b, b * cutout);
|
8053 |
+
const maxX = calcMax(0, startX, endX);
|
8054 |
+
const maxY = calcMax(HALF_PI, startY, endY);
|
8055 |
+
const minX = calcMin(PI, startX, endX);
|
8056 |
+
const minY = calcMin(PI + HALF_PI, startY, endY);
|
8057 |
+
ratioX = (maxX - minX) / 2;
|
8058 |
+
ratioY = (maxY - minY) / 2;
|
8059 |
+
offsetX = -(maxX + minX) / 2;
|
8060 |
+
offsetY = -(maxY + minY) / 2;
|
8061 |
+
}
|
8062 |
+
return {ratioX, ratioY, offsetX, offsetY};
|
8063 |
+
}
|
8064 |
+
class DoughnutController extends DatasetController {
|
8065 |
+
constructor(chart, datasetIndex) {
|
8066 |
+
super(chart, datasetIndex);
|
8067 |
+
this.enableOptionSharing = true;
|
8068 |
+
this.innerRadius = undefined;
|
8069 |
+
this.outerRadius = undefined;
|
8070 |
+
this.offsetX = undefined;
|
8071 |
+
this.offsetY = undefined;
|
8072 |
+
}
|
8073 |
+
linkScales() {}
|
8074 |
+
parse(start, count) {
|
8075 |
+
const data = this.getDataset().data;
|
8076 |
+
const meta = this._cachedMeta;
|
8077 |
+
if (this._parsing === false) {
|
8078 |
+
meta._parsed = data;
|
8079 |
+
} else {
|
8080 |
+
let getter = (i) => +data[i];
|
8081 |
+
if (isObject(data[start])) {
|
8082 |
+
const {key = 'value'} = this._parsing;
|
8083 |
+
getter = (i) => +resolveObjectKey(data[i], key);
|
8084 |
+
}
|
8085 |
+
let i, ilen;
|
8086 |
+
for (i = start, ilen = start + count; i < ilen; ++i) {
|
8087 |
+
meta._parsed[i] = getter(i);
|
8088 |
+
}
|
8089 |
+
}
|
8090 |
+
}
|
8091 |
+
_getRotation() {
|
8092 |
+
return toRadians(this.options.rotation - 90);
|
8093 |
+
}
|
8094 |
+
_getCircumference() {
|
8095 |
+
return toRadians(this.options.circumference);
|
8096 |
+
}
|
8097 |
+
_getRotationExtents() {
|
8098 |
+
let min = TAU;
|
8099 |
+
let max = -TAU;
|
8100 |
+
for (let i = 0; i < this.chart.data.datasets.length; ++i) {
|
8101 |
+
if (this.chart.isDatasetVisible(i)) {
|
8102 |
+
const controller = this.chart.getDatasetMeta(i).controller;
|
8103 |
+
const rotation = controller._getRotation();
|
8104 |
+
const circumference = controller._getCircumference();
|
8105 |
+
min = Math.min(min, rotation);
|
8106 |
+
max = Math.max(max, rotation + circumference);
|
8107 |
+
}
|
8108 |
+
}
|
8109 |
+
return {
|
8110 |
+
rotation: min,
|
8111 |
+
circumference: max - min,
|
8112 |
+
};
|
8113 |
+
}
|
8114 |
+
update(mode) {
|
8115 |
+
const chart = this.chart;
|
8116 |
+
const {chartArea} = chart;
|
8117 |
+
const meta = this._cachedMeta;
|
8118 |
+
const arcs = meta.data;
|
8119 |
+
const spacing = this.getMaxBorderWidth() + this.getMaxOffset(arcs) + this.options.spacing;
|
8120 |
+
const maxSize = Math.max((Math.min(chartArea.width, chartArea.height) - spacing) / 2, 0);
|
8121 |
+
const cutout = Math.min(toPercentage(this.options.cutout, maxSize), 1);
|
8122 |
+
const chartWeight = this._getRingWeight(this.index);
|
8123 |
+
const {circumference, rotation} = this._getRotationExtents();
|
8124 |
+
const {ratioX, ratioY, offsetX, offsetY} = getRatioAndOffset(rotation, circumference, cutout);
|
8125 |
+
const maxWidth = (chartArea.width - spacing) / ratioX;
|
8126 |
+
const maxHeight = (chartArea.height - spacing) / ratioY;
|
8127 |
+
const maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);
|
8128 |
+
const outerRadius = toDimension(this.options.radius, maxRadius);
|
8129 |
+
const innerRadius = Math.max(outerRadius * cutout, 0);
|
8130 |
+
const radiusLength = (outerRadius - innerRadius) / this._getVisibleDatasetWeightTotal();
|
8131 |
+
this.offsetX = offsetX * outerRadius;
|
8132 |
+
this.offsetY = offsetY * outerRadius;
|
8133 |
+
meta.total = this.calculateTotal();
|
8134 |
+
this.outerRadius = outerRadius - radiusLength * this._getRingWeightOffset(this.index);
|
8135 |
+
this.innerRadius = Math.max(this.outerRadius - radiusLength * chartWeight, 0);
|
8136 |
+
this.updateElements(arcs, 0, arcs.length, mode);
|
8137 |
+
}
|
8138 |
+
_circumference(i, reset) {
|
8139 |
+
const opts = this.options;
|
8140 |
+
const meta = this._cachedMeta;
|
8141 |
+
const circumference = this._getCircumference();
|
8142 |
+
if ((reset && opts.animation.animateRotate) || !this.chart.getDataVisibility(i) || meta._parsed[i] === null || meta.data[i].hidden) {
|
8143 |
+
return 0;
|
8144 |
+
}
|
8145 |
+
return this.calculateCircumference(meta._parsed[i] * circumference / TAU);
|
8146 |
+
}
|
8147 |
+
updateElements(arcs, start, count, mode) {
|
8148 |
+
const reset = mode === 'reset';
|
8149 |
+
const chart = this.chart;
|
8150 |
+
const chartArea = chart.chartArea;
|
8151 |
+
const opts = chart.options;
|
8152 |
+
const animationOpts = opts.animation;
|
8153 |
+
const centerX = (chartArea.left + chartArea.right) / 2;
|
8154 |
+
const centerY = (chartArea.top + chartArea.bottom) / 2;
|
8155 |
+
const animateScale = reset && animationOpts.animateScale;
|
8156 |
+
const innerRadius = animateScale ? 0 : this.innerRadius;
|
8157 |
+
const outerRadius = animateScale ? 0 : this.outerRadius;
|
8158 |
+
const firstOpts = this.resolveDataElementOptions(start, mode);
|
8159 |
+
const sharedOptions = this.getSharedOptions(firstOpts);
|
8160 |
+
const includeOptions = this.includeOptions(mode, sharedOptions);
|
8161 |
+
let startAngle = this._getRotation();
|
8162 |
+
let i;
|
8163 |
+
for (i = 0; i < start; ++i) {
|
8164 |
+
startAngle += this._circumference(i, reset);
|
8165 |
+
}
|
8166 |
+
for (i = start; i < start + count; ++i) {
|
8167 |
+
const circumference = this._circumference(i, reset);
|
8168 |
+
const arc = arcs[i];
|
8169 |
+
const properties = {
|
8170 |
+
x: centerX + this.offsetX,
|
8171 |
+
y: centerY + this.offsetY,
|
8172 |
+
startAngle,
|
8173 |
+
endAngle: startAngle + circumference,
|
8174 |
+
circumference,
|
8175 |
+
outerRadius,
|
8176 |
+
innerRadius
|
8177 |
+
};
|
8178 |
+
if (includeOptions) {
|
8179 |
+
properties.options = sharedOptions || this.resolveDataElementOptions(i, arc.active ? 'active' : mode);
|
8180 |
+
}
|
8181 |
+
startAngle += circumference;
|
8182 |
+
this.updateElement(arc, i, properties, mode);
|
8183 |
+
}
|
8184 |
+
this.updateSharedOptions(sharedOptions, mode, firstOpts);
|
8185 |
+
}
|
8186 |
+
calculateTotal() {
|
8187 |
+
const meta = this._cachedMeta;
|
8188 |
+
const metaData = meta.data;
|
8189 |
+
let total = 0;
|
8190 |
+
let i;
|
8191 |
+
for (i = 0; i < metaData.length; i++) {
|
8192 |
+
const value = meta._parsed[i];
|
8193 |
+
if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i) && !metaData[i].hidden) {
|
8194 |
+
total += Math.abs(value);
|
8195 |
+
}
|
8196 |
+
}
|
8197 |
+
return total;
|
8198 |
+
}
|
8199 |
+
calculateCircumference(value) {
|
8200 |
+
const total = this._cachedMeta.total;
|
8201 |
+
if (total > 0 && !isNaN(value)) {
|
8202 |
+
return TAU * (Math.abs(value) / total);
|
8203 |
+
}
|
8204 |
+
return 0;
|
8205 |
+
}
|
8206 |
+
getLabelAndValue(index) {
|
8207 |
+
const meta = this._cachedMeta;
|
8208 |
+
const chart = this.chart;
|
8209 |
+
const labels = chart.data.labels || [];
|
8210 |
+
const value = formatNumber(meta._parsed[index], chart.options.locale);
|
8211 |
+
return {
|
8212 |
+
label: labels[index] || '',
|
8213 |
+
value,
|
8214 |
+
};
|
8215 |
+
}
|
8216 |
+
getMaxBorderWidth(arcs) {
|
8217 |
+
let max = 0;
|
8218 |
+
const chart = this.chart;
|
8219 |
+
let i, ilen, meta, controller, options;
|
8220 |
+
if (!arcs) {
|
8221 |
+
for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) {
|
8222 |
+
if (chart.isDatasetVisible(i)) {
|
8223 |
+
meta = chart.getDatasetMeta(i);
|
8224 |
+
arcs = meta.data;
|
8225 |
+
controller = meta.controller;
|
8226 |
+
break;
|
8227 |
+
}
|
8228 |
+
}
|
8229 |
+
}
|
8230 |
+
if (!arcs) {
|
8231 |
+
return 0;
|
8232 |
+
}
|
8233 |
+
for (i = 0, ilen = arcs.length; i < ilen; ++i) {
|
8234 |
+
options = controller.resolveDataElementOptions(i);
|
8235 |
+
if (options.borderAlign !== 'inner') {
|
8236 |
+
max = Math.max(max, options.borderWidth || 0, options.hoverBorderWidth || 0);
|
8237 |
+
}
|
8238 |
+
}
|
8239 |
+
return max;
|
8240 |
+
}
|
8241 |
+
getMaxOffset(arcs) {
|
8242 |
+
let max = 0;
|
8243 |
+
for (let i = 0, ilen = arcs.length; i < ilen; ++i) {
|
8244 |
+
const options = this.resolveDataElementOptions(i);
|
8245 |
+
max = Math.max(max, options.offset || 0, options.hoverOffset || 0);
|
8246 |
+
}
|
8247 |
+
return max;
|
8248 |
+
}
|
8249 |
+
_getRingWeightOffset(datasetIndex) {
|
8250 |
+
let ringWeightOffset = 0;
|
8251 |
+
for (let i = 0; i < datasetIndex; ++i) {
|
8252 |
+
if (this.chart.isDatasetVisible(i)) {
|
8253 |
+
ringWeightOffset += this._getRingWeight(i);
|
8254 |
+
}
|
8255 |
+
}
|
8256 |
+
return ringWeightOffset;
|
8257 |
+
}
|
8258 |
+
_getRingWeight(datasetIndex) {
|
8259 |
+
return Math.max(valueOrDefault(this.chart.data.datasets[datasetIndex].weight, 1), 0);
|
8260 |
+
}
|
8261 |
+
_getVisibleDatasetWeightTotal() {
|
8262 |
+
return this._getRingWeightOffset(this.chart.data.datasets.length) || 1;
|
8263 |
+
}
|
8264 |
+
}
|
8265 |
+
DoughnutController.id = 'doughnut';
|
8266 |
+
DoughnutController.defaults = {
|
8267 |
+
datasetElementType: false,
|
8268 |
+
dataElementType: 'arc',
|
8269 |
+
animation: {
|
8270 |
+
animateRotate: true,
|
8271 |
+
animateScale: false
|
8272 |
+
},
|
8273 |
+
animations: {
|
8274 |
+
numbers: {
|
8275 |
+
type: 'number',
|
8276 |
+
properties: ['circumference', 'endAngle', 'innerRadius', 'outerRadius', 'startAngle', 'x', 'y', 'offset', 'borderWidth', 'spacing']
|
8277 |
+
},
|
8278 |
+
},
|
8279 |
+
cutout: '50%',
|
8280 |
+
rotation: 0,
|
8281 |
+
circumference: 360,
|
8282 |
+
radius: '100%',
|
8283 |
+
spacing: 0,
|
8284 |
+
indexAxis: 'r',
|
8285 |
+
};
|
8286 |
+
DoughnutController.descriptors = {
|
8287 |
+
_scriptable: (name) => name !== 'spacing',
|
8288 |
+
_indexable: (name) => name !== 'spacing',
|
8289 |
+
};
|
8290 |
+
DoughnutController.overrides = {
|
8291 |
+
aspectRatio: 1,
|
8292 |
+
plugins: {
|
8293 |
+
legend: {
|
8294 |
+
labels: {
|
8295 |
+
generateLabels(chart) {
|
8296 |
+
const data = chart.data;
|
8297 |
+
if (data.labels.length && data.datasets.length) {
|
8298 |
+
const {labels: {pointStyle}} = chart.legend.options;
|
8299 |
+
return data.labels.map((label, i) => {
|
8300 |
+
const meta = chart.getDatasetMeta(0);
|
8301 |
+
const style = meta.controller.getStyle(i);
|
8302 |
+
return {
|
8303 |
+
text: label,
|
8304 |
+
fillStyle: style.backgroundColor,
|
8305 |
+
strokeStyle: style.borderColor,
|
8306 |
+
lineWidth: style.borderWidth,
|
8307 |
+
pointStyle: pointStyle,
|
8308 |
+
hidden: !chart.getDataVisibility(i),
|
8309 |
+
index: i
|
8310 |
+
};
|
8311 |
+
});
|
8312 |
+
}
|
8313 |
+
return [];
|
8314 |
+
}
|
8315 |
+
},
|
8316 |
+
onClick(e, legendItem, legend) {
|
8317 |
+
legend.chart.toggleDataVisibility(legendItem.index);
|
8318 |
+
legend.chart.update();
|
8319 |
+
}
|
8320 |
+
},
|
8321 |
+
tooltip: {
|
8322 |
+
callbacks: {
|
8323 |
+
title() {
|
8324 |
+
return '';
|
8325 |
+
},
|
8326 |
+
label(tooltipItem) {
|
8327 |
+
let dataLabel = tooltipItem.label;
|
8328 |
+
const value = ': ' + tooltipItem.formattedValue;
|
8329 |
+
if (isArray(dataLabel)) {
|
8330 |
+
dataLabel = dataLabel.slice();
|
8331 |
+
dataLabel[0] += value;
|
8332 |
+
} else {
|
8333 |
+
dataLabel += value;
|
8334 |
+
}
|
8335 |
+
return dataLabel;
|
8336 |
+
}
|
8337 |
+
}
|
8338 |
+
}
|
8339 |
+
}
|
8340 |
+
};
|
8341 |
+
|
8342 |
+
class LineController extends DatasetController {
|
8343 |
+
initialize() {
|
8344 |
+
this.enableOptionSharing = true;
|
8345 |
+
super.initialize();
|
8346 |
+
}
|
8347 |
+
update(mode) {
|
8348 |
+
const meta = this._cachedMeta;
|
8349 |
+
const {dataset: line, data: points = [], _dataset} = meta;
|
8350 |
+
const animationsDisabled = this.chart._animationsDisabled;
|
8351 |
+
let {start, count} = getStartAndCountOfVisiblePoints(meta, points, animationsDisabled);
|
8352 |
+
this._drawStart = start;
|
8353 |
+
this._drawCount = count;
|
8354 |
+
if (scaleRangesChanged(meta)) {
|
8355 |
+
start = 0;
|
8356 |
+
count = points.length;
|
8357 |
+
}
|
8358 |
+
line._chart = this.chart;
|
8359 |
+
line._datasetIndex = this.index;
|
8360 |
+
line._decimated = !!_dataset._decimated;
|
8361 |
+
line.points = points;
|
8362 |
+
const options = this.resolveDatasetElementOptions(mode);
|
8363 |
+
if (!this.options.showLine) {
|
8364 |
+
options.borderWidth = 0;
|
8365 |
+
}
|
8366 |
+
options.segment = this.options.segment;
|
8367 |
+
this.updateElement(line, undefined, {
|
8368 |
+
animated: !animationsDisabled,
|
8369 |
+
options
|
8370 |
+
}, mode);
|
8371 |
+
this.updateElements(points, start, count, mode);
|
8372 |
+
}
|
8373 |
+
updateElements(points, start, count, mode) {
|
8374 |
+
const reset = mode === 'reset';
|
8375 |
+
const {iScale, vScale, _stacked, _dataset} = this._cachedMeta;
|
8376 |
+
const firstOpts = this.resolveDataElementOptions(start, mode);
|
8377 |
+
const sharedOptions = this.getSharedOptions(firstOpts);
|
8378 |
+
const includeOptions = this.includeOptions(mode, sharedOptions);
|
8379 |
+
const iAxis = iScale.axis;
|
8380 |
+
const vAxis = vScale.axis;
|
8381 |
+
const {spanGaps, segment} = this.options;
|
8382 |
+
const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;
|
8383 |
+
const directUpdate = this.chart._animationsDisabled || reset || mode === 'none';
|
8384 |
+
let prevParsed = start > 0 && this.getParsed(start - 1);
|
8385 |
+
for (let i = start; i < start + count; ++i) {
|
8386 |
+
const point = points[i];
|
8387 |
+
const parsed = this.getParsed(i);
|
8388 |
+
const properties = directUpdate ? point : {};
|
8389 |
+
const nullData = isNullOrUndef(parsed[vAxis]);
|
8390 |
+
const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i);
|
8391 |
+
const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i);
|
8392 |
+
properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData;
|
8393 |
+
properties.stop = i > 0 && (parsed[iAxis] - prevParsed[iAxis]) > maxGapLength;
|
8394 |
+
if (segment) {
|
8395 |
+
properties.parsed = parsed;
|
8396 |
+
properties.raw = _dataset.data[i];
|
8397 |
+
}
|
8398 |
+
if (includeOptions) {
|
8399 |
+
properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);
|
8400 |
+
}
|
8401 |
+
if (!directUpdate) {
|
8402 |
+
this.updateElement(point, i, properties, mode);
|
8403 |
+
}
|
8404 |
+
prevParsed = parsed;
|
8405 |
+
}
|
8406 |
+
this.updateSharedOptions(sharedOptions, mode, firstOpts);
|
8407 |
+
}
|
8408 |
+
getMaxOverflow() {
|
8409 |
+
const meta = this._cachedMeta;
|
8410 |
+
const dataset = meta.dataset;
|
8411 |
+
const border = dataset.options && dataset.options.borderWidth || 0;
|
8412 |
+
const data = meta.data || [];
|
8413 |
+
if (!data.length) {
|
8414 |
+
return border;
|
8415 |
+
}
|
8416 |
+
const firstPoint = data[0].size(this.resolveDataElementOptions(0));
|
8417 |
+
const lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1));
|
8418 |
+
return Math.max(border, firstPoint, lastPoint) / 2;
|
8419 |
+
}
|
8420 |
+
draw() {
|
8421 |
+
const meta = this._cachedMeta;
|
8422 |
+
meta.dataset.updateControlPoints(this.chart.chartArea, meta.iScale.axis);
|
8423 |
+
super.draw();
|
8424 |
+
}
|
8425 |
+
}
|
8426 |
+
LineController.id = 'line';
|
8427 |
+
LineController.defaults = {
|
8428 |
+
datasetElementType: 'line',
|
8429 |
+
dataElementType: 'point',
|
8430 |
+
showLine: true,
|
8431 |
+
spanGaps: false,
|
8432 |
+
};
|
8433 |
+
LineController.overrides = {
|
8434 |
+
scales: {
|
8435 |
+
_index_: {
|
8436 |
+
type: 'category',
|
8437 |
+
},
|
8438 |
+
_value_: {
|
8439 |
+
type: 'linear',
|
8440 |
+
},
|
8441 |
+
}
|
8442 |
+
};
|
8443 |
+
function getStartAndCountOfVisiblePoints(meta, points, animationsDisabled) {
|
8444 |
+
const pointCount = points.length;
|
8445 |
+
let start = 0;
|
8446 |
+
let count = pointCount;
|
8447 |
+
if (meta._sorted) {
|
8448 |
+
const {iScale, _parsed} = meta;
|
8449 |
+
const axis = iScale.axis;
|
8450 |
+
const {min, max, minDefined, maxDefined} = iScale.getUserBounds();
|
8451 |
+
if (minDefined) {
|
8452 |
+
start = _limitValue(Math.min(
|
8453 |
+
_lookupByKey(_parsed, iScale.axis, min).lo,
|
8454 |
+
animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo),
|
8455 |
+
0, pointCount - 1);
|
8456 |
+
}
|
8457 |
+
if (maxDefined) {
|
8458 |
+
count = _limitValue(Math.max(
|
8459 |
+
_lookupByKey(_parsed, iScale.axis, max).hi + 1,
|
8460 |
+
animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max)).hi + 1),
|
8461 |
+
start, pointCount) - start;
|
8462 |
+
} else {
|
8463 |
+
count = pointCount - start;
|
8464 |
+
}
|
8465 |
+
}
|
8466 |
+
return {start, count};
|
8467 |
+
}
|
8468 |
+
function scaleRangesChanged(meta) {
|
8469 |
+
const {xScale, yScale, _scaleRanges} = meta;
|
8470 |
+
const newRanges = {
|
8471 |
+
xmin: xScale.min,
|
8472 |
+
xmax: xScale.max,
|
8473 |
+
ymin: yScale.min,
|
8474 |
+
ymax: yScale.max
|
8475 |
+
};
|
8476 |
+
if (!_scaleRanges) {
|
8477 |
+
meta._scaleRanges = newRanges;
|
8478 |
+
return true;
|
8479 |
+
}
|
8480 |
+
const changed = _scaleRanges.xmin !== xScale.min
|
8481 |
+
|| _scaleRanges.xmax !== xScale.max
|
8482 |
+
|| _scaleRanges.ymin !== yScale.min
|
8483 |
+
|| _scaleRanges.ymax !== yScale.max;
|
8484 |
+
Object.assign(_scaleRanges, newRanges);
|
8485 |
+
return changed;
|
8486 |
+
}
|
8487 |
+
|
8488 |
+
class PolarAreaController extends DatasetController {
|
8489 |
+
constructor(chart, datasetIndex) {
|
8490 |
+
super(chart, datasetIndex);
|
8491 |
+
this.innerRadius = undefined;
|
8492 |
+
this.outerRadius = undefined;
|
8493 |
+
}
|
8494 |
+
getLabelAndValue(index) {
|
8495 |
+
const meta = this._cachedMeta;
|
8496 |
+
const chart = this.chart;
|
8497 |
+
const labels = chart.data.labels || [];
|
8498 |
+
const value = formatNumber(meta._parsed[index].r, chart.options.locale);
|
8499 |
+
return {
|
8500 |
+
label: labels[index] || '',
|
8501 |
+
value,
|
8502 |
+
};
|
8503 |
+
}
|
8504 |
+
update(mode) {
|
8505 |
+
const arcs = this._cachedMeta.data;
|
8506 |
+
this._updateRadius();
|
8507 |
+
this.updateElements(arcs, 0, arcs.length, mode);
|
8508 |
+
}
|
8509 |
+
_updateRadius() {
|
8510 |
+
const chart = this.chart;
|
8511 |
+
const chartArea = chart.chartArea;
|
8512 |
+
const opts = chart.options;
|
8513 |
+
const minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
|
8514 |
+
const outerRadius = Math.max(minSize / 2, 0);
|
8515 |
+
const innerRadius = Math.max(opts.cutoutPercentage ? (outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
|
8516 |
+
const radiusLength = (outerRadius - innerRadius) / chart.getVisibleDatasetCount();
|
8517 |
+
this.outerRadius = outerRadius - (radiusLength * this.index);
|
8518 |
+
this.innerRadius = this.outerRadius - radiusLength;
|
8519 |
+
}
|
8520 |
+
updateElements(arcs, start, count, mode) {
|
8521 |
+
const reset = mode === 'reset';
|
8522 |
+
const chart = this.chart;
|
8523 |
+
const dataset = this.getDataset();
|
8524 |
+
const opts = chart.options;
|
8525 |
+
const animationOpts = opts.animation;
|
8526 |
+
const scale = this._cachedMeta.rScale;
|
8527 |
+
const centerX = scale.xCenter;
|
8528 |
+
const centerY = scale.yCenter;
|
8529 |
+
const datasetStartAngle = scale.getIndexAngle(0) - 0.5 * PI;
|
8530 |
+
let angle = datasetStartAngle;
|
8531 |
+
let i;
|
8532 |
+
const defaultAngle = 360 / this.countVisibleElements();
|
8533 |
+
for (i = 0; i < start; ++i) {
|
8534 |
+
angle += this._computeAngle(i, mode, defaultAngle);
|
8535 |
+
}
|
8536 |
+
for (i = start; i < start + count; i++) {
|
8537 |
+
const arc = arcs[i];
|
8538 |
+
let startAngle = angle;
|
8539 |
+
let endAngle = angle + this._computeAngle(i, mode, defaultAngle);
|
8540 |
+
let outerRadius = chart.getDataVisibility(i) ? scale.getDistanceFromCenterForValue(dataset.data[i]) : 0;
|
8541 |
+
angle = endAngle;
|
8542 |
+
if (reset) {
|
8543 |
+
if (animationOpts.animateScale) {
|
8544 |
+
outerRadius = 0;
|
8545 |
+
}
|
8546 |
+
if (animationOpts.animateRotate) {
|
8547 |
+
startAngle = endAngle = datasetStartAngle;
|
8548 |
+
}
|
8549 |
+
}
|
8550 |
+
const properties = {
|
8551 |
+
x: centerX,
|
8552 |
+
y: centerY,
|
8553 |
+
innerRadius: 0,
|
8554 |
+
outerRadius,
|
8555 |
+
startAngle,
|
8556 |
+
endAngle,
|
8557 |
+
options: this.resolveDataElementOptions(i, arc.active ? 'active' : mode)
|
8558 |
+
};
|
8559 |
+
this.updateElement(arc, i, properties, mode);
|
8560 |
+
}
|
8561 |
+
}
|
8562 |
+
countVisibleElements() {
|
8563 |
+
const dataset = this.getDataset();
|
8564 |
+
const meta = this._cachedMeta;
|
8565 |
+
let count = 0;
|
8566 |
+
meta.data.forEach((element, index) => {
|
8567 |
+
if (!isNaN(dataset.data[index]) && this.chart.getDataVisibility(index)) {
|
8568 |
+
count++;
|
8569 |
+
}
|
8570 |
+
});
|
8571 |
+
return count;
|
8572 |
+
}
|
8573 |
+
_computeAngle(index, mode, defaultAngle) {
|
8574 |
+
return this.chart.getDataVisibility(index)
|
8575 |
+
? toRadians(this.resolveDataElementOptions(index, mode).angle || defaultAngle)
|
8576 |
+
: 0;
|
8577 |
+
}
|
8578 |
+
}
|
8579 |
+
PolarAreaController.id = 'polarArea';
|
8580 |
+
PolarAreaController.defaults = {
|
8581 |
+
dataElementType: 'arc',
|
8582 |
+
animation: {
|
8583 |
+
animateRotate: true,
|
8584 |
+
animateScale: true
|
8585 |
+
},
|
8586 |
+
animations: {
|
8587 |
+
numbers: {
|
8588 |
+
type: 'number',
|
8589 |
+
properties: ['x', 'y', 'startAngle', 'endAngle', 'innerRadius', 'outerRadius']
|
8590 |
+
},
|
8591 |
+
},
|
8592 |
+
indexAxis: 'r',
|
8593 |
+
startAngle: 0,
|
8594 |
+
};
|
8595 |
+
PolarAreaController.overrides = {
|
8596 |
+
aspectRatio: 1,
|
8597 |
+
plugins: {
|
8598 |
+
legend: {
|
8599 |
+
labels: {
|
8600 |
+
generateLabels(chart) {
|
8601 |
+
const data = chart.data;
|
8602 |
+
if (data.labels.length && data.datasets.length) {
|
8603 |
+
const {labels: {pointStyle}} = chart.legend.options;
|
8604 |
+
return data.labels.map((label, i) => {
|
8605 |
+
const meta = chart.getDatasetMeta(0);
|
8606 |
+
const style = meta.controller.getStyle(i);
|
8607 |
+
return {
|
8608 |
+
text: label,
|
8609 |
+
fillStyle: style.backgroundColor,
|
8610 |
+
strokeStyle: style.borderColor,
|
8611 |
+
lineWidth: style.borderWidth,
|
8612 |
+
pointStyle: pointStyle,
|
8613 |
+
hidden: !chart.getDataVisibility(i),
|
8614 |
+
index: i
|
8615 |
+
};
|
8616 |
+
});
|
8617 |
+
}
|
8618 |
+
return [];
|
8619 |
+
}
|
8620 |
+
},
|
8621 |
+
onClick(e, legendItem, legend) {
|
8622 |
+
legend.chart.toggleDataVisibility(legendItem.index);
|
8623 |
+
legend.chart.update();
|
8624 |
+
}
|
8625 |
+
},
|
8626 |
+
tooltip: {
|
8627 |
+
callbacks: {
|
8628 |
+
title() {
|
8629 |
+
return '';
|
8630 |
+
},
|
8631 |
+
label(context) {
|
8632 |
+
return context.chart.data.labels[context.dataIndex] + ': ' + context.formattedValue;
|
8633 |
+
}
|
8634 |
+
}
|
8635 |
+
}
|
8636 |
+
},
|
8637 |
+
scales: {
|
8638 |
+
r: {
|
8639 |
+
type: 'radialLinear',
|
8640 |
+
angleLines: {
|
8641 |
+
display: false
|
8642 |
+
},
|
8643 |
+
beginAtZero: true,
|
8644 |
+
grid: {
|
8645 |
+
circular: true
|
8646 |
+
},
|
8647 |
+
pointLabels: {
|
8648 |
+
display: false
|
8649 |
+
},
|
8650 |
+
startAngle: 0
|
8651 |
+
}
|
8652 |
+
}
|
8653 |
+
};
|
8654 |
+
|
8655 |
+
class PieController extends DoughnutController {
|
8656 |
+
}
|
8657 |
+
PieController.id = 'pie';
|
8658 |
+
PieController.defaults = {
|
8659 |
+
cutout: 0,
|
8660 |
+
rotation: 0,
|
8661 |
+
circumference: 360,
|
8662 |
+
radius: '100%'
|
8663 |
+
};
|
8664 |
+
|
8665 |
+
class RadarController extends DatasetController {
|
8666 |
+
getLabelAndValue(index) {
|
8667 |
+
const vScale = this._cachedMeta.vScale;
|
8668 |
+
const parsed = this.getParsed(index);
|
8669 |
+
return {
|
8670 |
+
label: vScale.getLabels()[index],
|
8671 |
+
value: '' + vScale.getLabelForValue(parsed[vScale.axis])
|
8672 |
+
};
|
8673 |
+
}
|
8674 |
+
update(mode) {
|
8675 |
+
const meta = this._cachedMeta;
|
8676 |
+
const line = meta.dataset;
|
8677 |
+
const points = meta.data || [];
|
8678 |
+
const labels = meta.iScale.getLabels();
|
8679 |
+
line.points = points;
|
8680 |
+
if (mode !== 'resize') {
|
8681 |
+
const options = this.resolveDatasetElementOptions(mode);
|
8682 |
+
if (!this.options.showLine) {
|
8683 |
+
options.borderWidth = 0;
|
8684 |
+
}
|
8685 |
+
const properties = {
|
8686 |
+
_loop: true,
|
8687 |
+
_fullLoop: labels.length === points.length,
|
8688 |
+
options
|
8689 |
+
};
|
8690 |
+
this.updateElement(line, undefined, properties, mode);
|
8691 |
+
}
|
8692 |
+
this.updateElements(points, 0, points.length, mode);
|
8693 |
+
}
|
8694 |
+
updateElements(points, start, count, mode) {
|
8695 |
+
const dataset = this.getDataset();
|
8696 |
+
const scale = this._cachedMeta.rScale;
|
8697 |
+
const reset = mode === 'reset';
|
8698 |
+
for (let i = start; i < start + count; i++) {
|
8699 |
+
const point = points[i];
|
8700 |
+
const options = this.resolveDataElementOptions(i, point.active ? 'active' : mode);
|
8701 |
+
const pointPosition = scale.getPointPositionForValue(i, dataset.data[i]);
|
8702 |
+
const x = reset ? scale.xCenter : pointPosition.x;
|
8703 |
+
const y = reset ? scale.yCenter : pointPosition.y;
|
8704 |
+
const properties = {
|
8705 |
+
x,
|
8706 |
+
y,
|
8707 |
+
angle: pointPosition.angle,
|
8708 |
+
skip: isNaN(x) || isNaN(y),
|
8709 |
+
options
|
8710 |
+
};
|
8711 |
+
this.updateElement(point, i, properties, mode);
|
8712 |
+
}
|
8713 |
+
}
|
8714 |
+
}
|
8715 |
+
RadarController.id = 'radar';
|
8716 |
+
RadarController.defaults = {
|
8717 |
+
datasetElementType: 'line',
|
8718 |
+
dataElementType: 'point',
|
8719 |
+
indexAxis: 'r',
|
8720 |
+
showLine: true,
|
8721 |
+
elements: {
|
8722 |
+
line: {
|
8723 |
+
fill: 'start'
|
8724 |
+
}
|
8725 |
+
},
|
8726 |
+
};
|
8727 |
+
RadarController.overrides = {
|
8728 |
+
aspectRatio: 1,
|
8729 |
+
scales: {
|
8730 |
+
r: {
|
8731 |
+
type: 'radialLinear',
|
8732 |
+
}
|
8733 |
+
}
|
8734 |
+
};
|
8735 |
+
|
8736 |
+
class ScatterController extends LineController {
|
8737 |
+
}
|
8738 |
+
ScatterController.id = 'scatter';
|
8739 |
+
ScatterController.defaults = {
|
8740 |
+
showLine: false,
|
8741 |
+
fill: false
|
8742 |
+
};
|
8743 |
+
ScatterController.overrides = {
|
8744 |
+
interaction: {
|
8745 |
+
mode: 'point'
|
8746 |
+
},
|
8747 |
+
plugins: {
|
8748 |
+
tooltip: {
|
8749 |
+
callbacks: {
|
8750 |
+
title() {
|
8751 |
+
return '';
|
8752 |
+
},
|
8753 |
+
label(item) {
|
8754 |
+
return '(' + item.label + ', ' + item.formattedValue + ')';
|
8755 |
+
}
|
8756 |
+
}
|
8757 |
+
}
|
8758 |
+
},
|
8759 |
+
scales: {
|
8760 |
+
x: {
|
8761 |
+
type: 'linear'
|
8762 |
+
},
|
8763 |
+
y: {
|
8764 |
+
type: 'linear'
|
8765 |
+
}
|
8766 |
+
}
|
8767 |
+
};
|
8768 |
+
|
8769 |
+
var controllers = /*#__PURE__*/Object.freeze({
|
8770 |
+
__proto__: null,
|
8771 |
+
BarController: BarController,
|
8772 |
+
BubbleController: BubbleController,
|
8773 |
+
DoughnutController: DoughnutController,
|
8774 |
+
LineController: LineController,
|
8775 |
+
PolarAreaController: PolarAreaController,
|
8776 |
+
PieController: PieController,
|
8777 |
+
RadarController: RadarController,
|
8778 |
+
ScatterController: ScatterController
|
8779 |
+
});
|
8780 |
+
|
8781 |
+
function clipArc(ctx, element, endAngle) {
|
8782 |
+
const {startAngle, pixelMargin, x, y, outerRadius, innerRadius} = element;
|
8783 |
+
let angleMargin = pixelMargin / outerRadius;
|
8784 |
+
ctx.beginPath();
|
8785 |
+
ctx.arc(x, y, outerRadius, startAngle - angleMargin, endAngle + angleMargin);
|
8786 |
+
if (innerRadius > pixelMargin) {
|
8787 |
+
angleMargin = pixelMargin / innerRadius;
|
8788 |
+
ctx.arc(x, y, innerRadius, endAngle + angleMargin, startAngle - angleMargin, true);
|
8789 |
+
} else {
|
8790 |
+
ctx.arc(x, y, pixelMargin, endAngle + HALF_PI, startAngle - HALF_PI);
|
8791 |
+
}
|
8792 |
+
ctx.closePath();
|
8793 |
+
ctx.clip();
|
8794 |
+
}
|
8795 |
+
function toRadiusCorners(value) {
|
8796 |
+
return _readValueToProps(value, ['outerStart', 'outerEnd', 'innerStart', 'innerEnd']);
|
8797 |
+
}
|
8798 |
+
function parseBorderRadius$1(arc, innerRadius, outerRadius, angleDelta) {
|
8799 |
+
const o = toRadiusCorners(arc.options.borderRadius);
|
8800 |
+
const halfThickness = (outerRadius - innerRadius) / 2;
|
8801 |
+
const innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2);
|
8802 |
+
const computeOuterLimit = (val) => {
|
8803 |
+
const outerArcLimit = (outerRadius - Math.min(halfThickness, val)) * angleDelta / 2;
|
8804 |
+
return _limitValue(val, 0, Math.min(halfThickness, outerArcLimit));
|
8805 |
+
};
|
8806 |
+
return {
|
8807 |
+
outerStart: computeOuterLimit(o.outerStart),
|
8808 |
+
outerEnd: computeOuterLimit(o.outerEnd),
|
8809 |
+
innerStart: _limitValue(o.innerStart, 0, innerLimit),
|
8810 |
+
innerEnd: _limitValue(o.innerEnd, 0, innerLimit),
|
8811 |
+
};
|
8812 |
+
}
|
8813 |
+
function rThetaToXY(r, theta, x, y) {
|
8814 |
+
return {
|
8815 |
+
x: x + r * Math.cos(theta),
|
8816 |
+
y: y + r * Math.sin(theta),
|
8817 |
+
};
|
8818 |
+
}
|
8819 |
+
function pathArc(ctx, element, offset, spacing, end) {
|
8820 |
+
const {x, y, startAngle: start, pixelMargin, innerRadius: innerR} = element;
|
8821 |
+
const outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0);
|
8822 |
+
const innerRadius = innerR > 0 ? innerR + spacing + offset + pixelMargin : 0;
|
8823 |
+
let spacingOffset = 0;
|
8824 |
+
const alpha = end - start;
|
8825 |
+
if (spacing) {
|
8826 |
+
const noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0;
|
8827 |
+
const noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0;
|
8828 |
+
const avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2;
|
8829 |
+
const adjustedAngle = avNogSpacingRadius !== 0 ? (alpha * avNogSpacingRadius) / (avNogSpacingRadius + spacing) : alpha;
|
8830 |
+
spacingOffset = (alpha - adjustedAngle) / 2;
|
8831 |
+
}
|
8832 |
+
const beta = Math.max(0.001, alpha * outerRadius - offset / PI) / outerRadius;
|
8833 |
+
const angleOffset = (alpha - beta) / 2;
|
8834 |
+
const startAngle = start + angleOffset + spacingOffset;
|
8835 |
+
const endAngle = end - angleOffset - spacingOffset;
|
8836 |
+
const {outerStart, outerEnd, innerStart, innerEnd} = parseBorderRadius$1(element, innerRadius, outerRadius, endAngle - startAngle);
|
8837 |
+
const outerStartAdjustedRadius = outerRadius - outerStart;
|
8838 |
+
const outerEndAdjustedRadius = outerRadius - outerEnd;
|
8839 |
+
const outerStartAdjustedAngle = startAngle + outerStart / outerStartAdjustedRadius;
|
8840 |
+
const outerEndAdjustedAngle = endAngle - outerEnd / outerEndAdjustedRadius;
|
8841 |
+
const innerStartAdjustedRadius = innerRadius + innerStart;
|
8842 |
+
const innerEndAdjustedRadius = innerRadius + innerEnd;
|
8843 |
+
const innerStartAdjustedAngle = startAngle + innerStart / innerStartAdjustedRadius;
|
8844 |
+
const innerEndAdjustedAngle = endAngle - innerEnd / innerEndAdjustedRadius;
|
8845 |
+
ctx.beginPath();
|
8846 |
+
ctx.arc(x, y, outerRadius, outerStartAdjustedAngle, outerEndAdjustedAngle);
|
8847 |
+
if (outerEnd > 0) {
|
8848 |
+
const pCenter = rThetaToXY(outerEndAdjustedRadius, outerEndAdjustedAngle, x, y);
|
8849 |
+
ctx.arc(pCenter.x, pCenter.y, outerEnd, outerEndAdjustedAngle, endAngle + HALF_PI);
|
8850 |
+
}
|
8851 |
+
const p4 = rThetaToXY(innerEndAdjustedRadius, endAngle, x, y);
|
8852 |
+
ctx.lineTo(p4.x, p4.y);
|
8853 |
+
if (innerEnd > 0) {
|
8854 |
+
const pCenter = rThetaToXY(innerEndAdjustedRadius, innerEndAdjustedAngle, x, y);
|
8855 |
+
ctx.arc(pCenter.x, pCenter.y, innerEnd, endAngle + HALF_PI, innerEndAdjustedAngle + Math.PI);
|
8856 |
+
}
|
8857 |
+
ctx.arc(x, y, innerRadius, endAngle - (innerEnd / innerRadius), startAngle + (innerStart / innerRadius), true);
|
8858 |
+
if (innerStart > 0) {
|
8859 |
+
const pCenter = rThetaToXY(innerStartAdjustedRadius, innerStartAdjustedAngle, x, y);
|
8860 |
+
ctx.arc(pCenter.x, pCenter.y, innerStart, innerStartAdjustedAngle + Math.PI, startAngle - HALF_PI);
|
8861 |
+
}
|
8862 |
+
const p8 = rThetaToXY(outerStartAdjustedRadius, startAngle, x, y);
|
8863 |
+
ctx.lineTo(p8.x, p8.y);
|
8864 |
+
if (outerStart > 0) {
|
8865 |
+
const pCenter = rThetaToXY(outerStartAdjustedRadius, outerStartAdjustedAngle, x, y);
|
8866 |
+
ctx.arc(pCenter.x, pCenter.y, outerStart, startAngle - HALF_PI, outerStartAdjustedAngle);
|
8867 |
+
}
|
8868 |
+
ctx.closePath();
|
8869 |
+
}
|
8870 |
+
function drawArc(ctx, element, offset, spacing) {
|
8871 |
+
const {fullCircles, startAngle, circumference} = element;
|
8872 |
+
let endAngle = element.endAngle;
|
8873 |
+
if (fullCircles) {
|
8874 |
+
pathArc(ctx, element, offset, spacing, startAngle + TAU);
|
8875 |
+
for (let i = 0; i < fullCircles; ++i) {
|
8876 |
+
ctx.fill();
|
8877 |
+
}
|
8878 |
+
if (!isNaN(circumference)) {
|
8879 |
+
endAngle = startAngle + circumference % TAU;
|
8880 |
+
if (circumference % TAU === 0) {
|
8881 |
+
endAngle += TAU;
|
8882 |
+
}
|
8883 |
+
}
|
8884 |
+
}
|
8885 |
+
pathArc(ctx, element, offset, spacing, endAngle);
|
8886 |
+
ctx.fill();
|
8887 |
+
return endAngle;
|
8888 |
+
}
|
8889 |
+
function drawFullCircleBorders(ctx, element, inner) {
|
8890 |
+
const {x, y, startAngle, pixelMargin, fullCircles} = element;
|
8891 |
+
const outerRadius = Math.max(element.outerRadius - pixelMargin, 0);
|
8892 |
+
const innerRadius = element.innerRadius + pixelMargin;
|
8893 |
+
let i;
|
8894 |
+
if (inner) {
|
8895 |
+
clipArc(ctx, element, startAngle + TAU);
|
8896 |
+
}
|
8897 |
+
ctx.beginPath();
|
8898 |
+
ctx.arc(x, y, innerRadius, startAngle + TAU, startAngle, true);
|
8899 |
+
for (i = 0; i < fullCircles; ++i) {
|
8900 |
+
ctx.stroke();
|
8901 |
+
}
|
8902 |
+
ctx.beginPath();
|
8903 |
+
ctx.arc(x, y, outerRadius, startAngle, startAngle + TAU);
|
8904 |
+
for (i = 0; i < fullCircles; ++i) {
|
8905 |
+
ctx.stroke();
|
8906 |
+
}
|
8907 |
+
}
|
8908 |
+
function drawBorder(ctx, element, offset, spacing, endAngle) {
|
8909 |
+
const {options} = element;
|
8910 |
+
const {borderWidth, borderJoinStyle} = options;
|
8911 |
+
const inner = options.borderAlign === 'inner';
|
8912 |
+
if (!borderWidth) {
|
8913 |
+
return;
|
8914 |
+
}
|
8915 |
+
if (inner) {
|
8916 |
+
ctx.lineWidth = borderWidth * 2;
|
8917 |
+
ctx.lineJoin = borderJoinStyle || 'round';
|
8918 |
+
} else {
|
8919 |
+
ctx.lineWidth = borderWidth;
|
8920 |
+
ctx.lineJoin = borderJoinStyle || 'bevel';
|
8921 |
+
}
|
8922 |
+
if (element.fullCircles) {
|
8923 |
+
drawFullCircleBorders(ctx, element, inner);
|
8924 |
+
}
|
8925 |
+
if (inner) {
|
8926 |
+
clipArc(ctx, element, endAngle);
|
8927 |
+
}
|
8928 |
+
pathArc(ctx, element, offset, spacing, endAngle);
|
8929 |
+
ctx.stroke();
|
8930 |
+
}
|
8931 |
+
class ArcElement extends Element {
|
8932 |
+
constructor(cfg) {
|
8933 |
+
super();
|
8934 |
+
this.options = undefined;
|
8935 |
+
this.circumference = undefined;
|
8936 |
+
this.startAngle = undefined;
|
8937 |
+
this.endAngle = undefined;
|
8938 |
+
this.innerRadius = undefined;
|
8939 |
+
this.outerRadius = undefined;
|
8940 |
+
this.pixelMargin = 0;
|
8941 |
+
this.fullCircles = 0;
|
8942 |
+
if (cfg) {
|
8943 |
+
Object.assign(this, cfg);
|
8944 |
+
}
|
8945 |
+
}
|
8946 |
+
inRange(chartX, chartY, useFinalPosition) {
|
8947 |
+
const point = this.getProps(['x', 'y'], useFinalPosition);
|
8948 |
+
const {angle, distance} = getAngleFromPoint(point, {x: chartX, y: chartY});
|
8949 |
+
const {startAngle, endAngle, innerRadius, outerRadius, circumference} = this.getProps([
|
8950 |
+
'startAngle',
|
8951 |
+
'endAngle',
|
8952 |
+
'innerRadius',
|
8953 |
+
'outerRadius',
|
8954 |
+
'circumference'
|
8955 |
+
], useFinalPosition);
|
8956 |
+
const rAdjust = this.options.spacing / 2;
|
8957 |
+
const _circumference = valueOrDefault(circumference, endAngle - startAngle);
|
8958 |
+
const betweenAngles = _circumference >= TAU || _angleBetween(angle, startAngle, endAngle);
|
8959 |
+
const withinRadius = _isBetween(distance, innerRadius + rAdjust, outerRadius + rAdjust);
|
8960 |
+
return (betweenAngles && withinRadius);
|
8961 |
+
}
|
8962 |
+
getCenterPoint(useFinalPosition) {
|
8963 |
+
const {x, y, startAngle, endAngle, innerRadius, outerRadius} = this.getProps([
|
8964 |
+
'x',
|
8965 |
+
'y',
|
8966 |
+
'startAngle',
|
8967 |
+
'endAngle',
|
8968 |
+
'innerRadius',
|
8969 |
+
'outerRadius',
|
8970 |
+
'circumference',
|
8971 |
+
], useFinalPosition);
|
8972 |
+
const {offset, spacing} = this.options;
|
8973 |
+
const halfAngle = (startAngle + endAngle) / 2;
|
8974 |
+
const halfRadius = (innerRadius + outerRadius + spacing + offset) / 2;
|
8975 |
+
return {
|
8976 |
+
x: x + Math.cos(halfAngle) * halfRadius,
|
8977 |
+
y: y + Math.sin(halfAngle) * halfRadius
|
8978 |
+
};
|
8979 |
+
}
|
8980 |
+
tooltipPosition(useFinalPosition) {
|
8981 |
+
return this.getCenterPoint(useFinalPosition);
|
8982 |
+
}
|
8983 |
+
draw(ctx) {
|
8984 |
+
const {options, circumference} = this;
|
8985 |
+
const offset = (options.offset || 0) / 2;
|
8986 |
+
const spacing = (options.spacing || 0) / 2;
|
8987 |
+
this.pixelMargin = (options.borderAlign === 'inner') ? 0.33 : 0;
|
8988 |
+
this.fullCircles = circumference > TAU ? Math.floor(circumference / TAU) : 0;
|
8989 |
+
if (circumference === 0 || this.innerRadius < 0 || this.outerRadius < 0) {
|
8990 |
+
return;
|
8991 |
+
}
|
8992 |
+
ctx.save();
|
8993 |
+
let radiusOffset = 0;
|
8994 |
+
if (offset) {
|
8995 |
+
radiusOffset = offset / 2;
|
8996 |
+
const halfAngle = (this.startAngle + this.endAngle) / 2;
|
8997 |
+
ctx.translate(Math.cos(halfAngle) * radiusOffset, Math.sin(halfAngle) * radiusOffset);
|
8998 |
+
if (this.circumference >= PI) {
|
8999 |
+
radiusOffset = offset;
|
9000 |
+
}
|
9001 |
+
}
|
9002 |
+
ctx.fillStyle = options.backgroundColor;
|
9003 |
+
ctx.strokeStyle = options.borderColor;
|
9004 |
+
const endAngle = drawArc(ctx, this, radiusOffset, spacing);
|
9005 |
+
drawBorder(ctx, this, radiusOffset, spacing, endAngle);
|
9006 |
+
ctx.restore();
|
9007 |
+
}
|
9008 |
+
}
|
9009 |
+
ArcElement.id = 'arc';
|
9010 |
+
ArcElement.defaults = {
|
9011 |
+
borderAlign: 'center',
|
9012 |
+
borderColor: '#fff',
|
9013 |
+
borderJoinStyle: undefined,
|
9014 |
+
borderRadius: 0,
|
9015 |
+
borderWidth: 2,
|
9016 |
+
offset: 0,
|
9017 |
+
spacing: 0,
|
9018 |
+
angle: undefined,
|
9019 |
+
};
|
9020 |
+
ArcElement.defaultRoutes = {
|
9021 |
+
backgroundColor: 'backgroundColor'
|
9022 |
+
};
|
9023 |
+
|
9024 |
+
function setStyle(ctx, options, style = options) {
|
9025 |
+
ctx.lineCap = valueOrDefault(style.borderCapStyle, options.borderCapStyle);
|
9026 |
+
ctx.setLineDash(valueOrDefault(style.borderDash, options.borderDash));
|
9027 |
+
ctx.lineDashOffset = valueOrDefault(style.borderDashOffset, options.borderDashOffset);
|
9028 |
+
ctx.lineJoin = valueOrDefault(style.borderJoinStyle, options.borderJoinStyle);
|
9029 |
+
ctx.lineWidth = valueOrDefault(style.borderWidth, options.borderWidth);
|
9030 |
+
ctx.strokeStyle = valueOrDefault(style.borderColor, options.borderColor);
|
9031 |
+
}
|
9032 |
+
function lineTo(ctx, previous, target) {
|
9033 |
+
ctx.lineTo(target.x, target.y);
|
9034 |
+
}
|
9035 |
+
function getLineMethod(options) {
|
9036 |
+
if (options.stepped) {
|
9037 |
+
return _steppedLineTo;
|
9038 |
+
}
|
9039 |
+
if (options.tension || options.cubicInterpolationMode === 'monotone') {
|
9040 |
+
return _bezierCurveTo;
|
9041 |
+
}
|
9042 |
+
return lineTo;
|
9043 |
+
}
|
9044 |
+
function pathVars(points, segment, params = {}) {
|
9045 |
+
const count = points.length;
|
9046 |
+
const {start: paramsStart = 0, end: paramsEnd = count - 1} = params;
|
9047 |
+
const {start: segmentStart, end: segmentEnd} = segment;
|
9048 |
+
const start = Math.max(paramsStart, segmentStart);
|
9049 |
+
const end = Math.min(paramsEnd, segmentEnd);
|
9050 |
+
const outside = paramsStart < segmentStart && paramsEnd < segmentStart || paramsStart > segmentEnd && paramsEnd > segmentEnd;
|
9051 |
+
return {
|
9052 |
+
count,
|
9053 |
+
start,
|
9054 |
+
loop: segment.loop,
|
9055 |
+
ilen: end < start && !outside ? count + end - start : end - start
|
9056 |
+
};
|
9057 |
+
}
|
9058 |
+
function pathSegment(ctx, line, segment, params) {
|
9059 |
+
const {points, options} = line;
|
9060 |
+
const {count, start, loop, ilen} = pathVars(points, segment, params);
|
9061 |
+
const lineMethod = getLineMethod(options);
|
9062 |
+
let {move = true, reverse} = params || {};
|
9063 |
+
let i, point, prev;
|
9064 |
+
for (i = 0; i <= ilen; ++i) {
|
9065 |
+
point = points[(start + (reverse ? ilen - i : i)) % count];
|
9066 |
+
if (point.skip) {
|
9067 |
+
continue;
|
9068 |
+
} else if (move) {
|
9069 |
+
ctx.moveTo(point.x, point.y);
|
9070 |
+
move = false;
|
9071 |
+
} else {
|
9072 |
+
lineMethod(ctx, prev, point, reverse, options.stepped);
|
9073 |
+
}
|
9074 |
+
prev = point;
|
9075 |
+
}
|
9076 |
+
if (loop) {
|
9077 |
+
point = points[(start + (reverse ? ilen : 0)) % count];
|
9078 |
+
lineMethod(ctx, prev, point, reverse, options.stepped);
|
9079 |
+
}
|
9080 |
+
return !!loop;
|
9081 |
+
}
|
9082 |
+
function fastPathSegment(ctx, line, segment, params) {
|
9083 |
+
const points = line.points;
|
9084 |
+
const {count, start, ilen} = pathVars(points, segment, params);
|
9085 |
+
const {move = true, reverse} = params || {};
|
9086 |
+
let avgX = 0;
|
9087 |
+
let countX = 0;
|
9088 |
+
let i, point, prevX, minY, maxY, lastY;
|
9089 |
+
const pointIndex = (index) => (start + (reverse ? ilen - index : index)) % count;
|
9090 |
+
const drawX = () => {
|
9091 |
+
if (minY !== maxY) {
|
9092 |
+
ctx.lineTo(avgX, maxY);
|
9093 |
+
ctx.lineTo(avgX, minY);
|
9094 |
+
ctx.lineTo(avgX, lastY);
|
9095 |
+
}
|
9096 |
+
};
|
9097 |
+
if (move) {
|
9098 |
+
point = points[pointIndex(0)];
|
9099 |
+
ctx.moveTo(point.x, point.y);
|
9100 |
+
}
|
9101 |
+
for (i = 0; i <= ilen; ++i) {
|
9102 |
+
point = points[pointIndex(i)];
|
9103 |
+
if (point.skip) {
|
9104 |
+
continue;
|
9105 |
+
}
|
9106 |
+
const x = point.x;
|
9107 |
+
const y = point.y;
|
9108 |
+
const truncX = x | 0;
|
9109 |
+
if (truncX === prevX) {
|
9110 |
+
if (y < minY) {
|
9111 |
+
minY = y;
|
9112 |
+
} else if (y > maxY) {
|
9113 |
+
maxY = y;
|
9114 |
+
}
|
9115 |
+
avgX = (countX * avgX + x) / ++countX;
|
9116 |
+
} else {
|
9117 |
+
drawX();
|
9118 |
+
ctx.lineTo(x, y);
|
9119 |
+
prevX = truncX;
|
9120 |
+
countX = 0;
|
9121 |
+
minY = maxY = y;
|
9122 |
+
}
|
9123 |
+
lastY = y;
|
9124 |
+
}
|
9125 |
+
drawX();
|
9126 |
+
}
|
9127 |
+
function _getSegmentMethod(line) {
|
9128 |
+
const opts = line.options;
|
9129 |
+
const borderDash = opts.borderDash && opts.borderDash.length;
|
9130 |
+
const useFastPath = !line._decimated && !line._loop && !opts.tension && opts.cubicInterpolationMode !== 'monotone' && !opts.stepped && !borderDash;
|
9131 |
+
return useFastPath ? fastPathSegment : pathSegment;
|
9132 |
+
}
|
9133 |
+
function _getInterpolationMethod(options) {
|
9134 |
+
if (options.stepped) {
|
9135 |
+
return _steppedInterpolation;
|
9136 |
+
}
|
9137 |
+
if (options.tension || options.cubicInterpolationMode === 'monotone') {
|
9138 |
+
return _bezierInterpolation;
|
9139 |
+
}
|
9140 |
+
return _pointInLine;
|
9141 |
+
}
|
9142 |
+
function strokePathWithCache(ctx, line, start, count) {
|
9143 |
+
let path = line._path;
|
9144 |
+
if (!path) {
|
9145 |
+
path = line._path = new Path2D();
|
9146 |
+
if (line.path(path, start, count)) {
|
9147 |
+
path.closePath();
|
9148 |
+
}
|
9149 |
+
}
|
9150 |
+
setStyle(ctx, line.options);
|
9151 |
+
ctx.stroke(path);
|
9152 |
+
}
|
9153 |
+
function strokePathDirect(ctx, line, start, count) {
|
9154 |
+
const {segments, options} = line;
|
9155 |
+
const segmentMethod = _getSegmentMethod(line);
|
9156 |
+
for (const segment of segments) {
|
9157 |
+
setStyle(ctx, options, segment.style);
|
9158 |
+
ctx.beginPath();
|
9159 |
+
if (segmentMethod(ctx, line, segment, {start, end: start + count - 1})) {
|
9160 |
+
ctx.closePath();
|
9161 |
+
}
|
9162 |
+
ctx.stroke();
|
9163 |
+
}
|
9164 |
+
}
|
9165 |
+
const usePath2D = typeof Path2D === 'function';
|
9166 |
+
function draw(ctx, line, start, count) {
|
9167 |
+
if (usePath2D && !line.options.segment) {
|
9168 |
+
strokePathWithCache(ctx, line, start, count);
|
9169 |
+
} else {
|
9170 |
+
strokePathDirect(ctx, line, start, count);
|
9171 |
+
}
|
9172 |
+
}
|
9173 |
+
class LineElement extends Element {
|
9174 |
+
constructor(cfg) {
|
9175 |
+
super();
|
9176 |
+
this.animated = true;
|
9177 |
+
this.options = undefined;
|
9178 |
+
this._chart = undefined;
|
9179 |
+
this._loop = undefined;
|
9180 |
+
this._fullLoop = undefined;
|
9181 |
+
this._path = undefined;
|
9182 |
+
this._points = undefined;
|
9183 |
+
this._segments = undefined;
|
9184 |
+
this._decimated = false;
|
9185 |
+
this._pointsUpdated = false;
|
9186 |
+
this._datasetIndex = undefined;
|
9187 |
+
if (cfg) {
|
9188 |
+
Object.assign(this, cfg);
|
9189 |
+
}
|
9190 |
+
}
|
9191 |
+
updateControlPoints(chartArea, indexAxis) {
|
9192 |
+
const options = this.options;
|
9193 |
+
if ((options.tension || options.cubicInterpolationMode === 'monotone') && !options.stepped && !this._pointsUpdated) {
|
9194 |
+
const loop = options.spanGaps ? this._loop : this._fullLoop;
|
9195 |
+
_updateBezierControlPoints(this._points, options, chartArea, loop, indexAxis);
|
9196 |
+
this._pointsUpdated = true;
|
9197 |
+
}
|
9198 |
+
}
|
9199 |
+
set points(points) {
|
9200 |
+
this._points = points;
|
9201 |
+
delete this._segments;
|
9202 |
+
delete this._path;
|
9203 |
+
this._pointsUpdated = false;
|
9204 |
+
}
|
9205 |
+
get points() {
|
9206 |
+
return this._points;
|
9207 |
+
}
|
9208 |
+
get segments() {
|
9209 |
+
return this._segments || (this._segments = _computeSegments(this, this.options.segment));
|
9210 |
+
}
|
9211 |
+
first() {
|
9212 |
+
const segments = this.segments;
|
9213 |
+
const points = this.points;
|
9214 |
+
return segments.length && points[segments[0].start];
|
9215 |
+
}
|
9216 |
+
last() {
|
9217 |
+
const segments = this.segments;
|
9218 |
+
const points = this.points;
|
9219 |
+
const count = segments.length;
|
9220 |
+
return count && points[segments[count - 1].end];
|
9221 |
+
}
|
9222 |
+
interpolate(point, property) {
|
9223 |
+
const options = this.options;
|
9224 |
+
const value = point[property];
|
9225 |
+
const points = this.points;
|
9226 |
+
const segments = _boundSegments(this, {property, start: value, end: value});
|
9227 |
+
if (!segments.length) {
|
9228 |
+
return;
|
9229 |
+
}
|
9230 |
+
const result = [];
|
9231 |
+
const _interpolate = _getInterpolationMethod(options);
|
9232 |
+
let i, ilen;
|
9233 |
+
for (i = 0, ilen = segments.length; i < ilen; ++i) {
|
9234 |
+
const {start, end} = segments[i];
|
9235 |
+
const p1 = points[start];
|
9236 |
+
const p2 = points[end];
|
9237 |
+
if (p1 === p2) {
|
9238 |
+
result.push(p1);
|
9239 |
+
continue;
|
9240 |
+
}
|
9241 |
+
const t = Math.abs((value - p1[property]) / (p2[property] - p1[property]));
|
9242 |
+
const interpolated = _interpolate(p1, p2, t, options.stepped);
|
9243 |
+
interpolated[property] = point[property];
|
9244 |
+
result.push(interpolated);
|
9245 |
+
}
|
9246 |
+
return result.length === 1 ? result[0] : result;
|
9247 |
+
}
|
9248 |
+
pathSegment(ctx, segment, params) {
|
9249 |
+
const segmentMethod = _getSegmentMethod(this);
|
9250 |
+
return segmentMethod(ctx, this, segment, params);
|
9251 |
+
}
|
9252 |
+
path(ctx, start, count) {
|
9253 |
+
const segments = this.segments;
|
9254 |
+
const segmentMethod = _getSegmentMethod(this);
|
9255 |
+
let loop = this._loop;
|
9256 |
+
start = start || 0;
|
9257 |
+
count = count || (this.points.length - start);
|
9258 |
+
for (const segment of segments) {
|
9259 |
+
loop &= segmentMethod(ctx, this, segment, {start, end: start + count - 1});
|
9260 |
+
}
|
9261 |
+
return !!loop;
|
9262 |
+
}
|
9263 |
+
draw(ctx, chartArea, start, count) {
|
9264 |
+
const options = this.options || {};
|
9265 |
+
const points = this.points || [];
|
9266 |
+
if (points.length && options.borderWidth) {
|
9267 |
+
ctx.save();
|
9268 |
+
draw(ctx, this, start, count);
|
9269 |
+
ctx.restore();
|
9270 |
+
}
|
9271 |
+
if (this.animated) {
|
9272 |
+
this._pointsUpdated = false;
|
9273 |
+
this._path = undefined;
|
9274 |
+
}
|
9275 |
+
}
|
9276 |
+
}
|
9277 |
+
LineElement.id = 'line';
|
9278 |
+
LineElement.defaults = {
|
9279 |
+
borderCapStyle: 'butt',
|
9280 |
+
borderDash: [],
|
9281 |
+
borderDashOffset: 0,
|
9282 |
+
borderJoinStyle: 'miter',
|
9283 |
+
borderWidth: 3,
|
9284 |
+
capBezierPoints: true,
|
9285 |
+
cubicInterpolationMode: 'default',
|
9286 |
+
fill: false,
|
9287 |
+
spanGaps: false,
|
9288 |
+
stepped: false,
|
9289 |
+
tension: 0,
|
9290 |
+
};
|
9291 |
+
LineElement.defaultRoutes = {
|
9292 |
+
backgroundColor: 'backgroundColor',
|
9293 |
+
borderColor: 'borderColor'
|
9294 |
+
};
|
9295 |
+
LineElement.descriptors = {
|
9296 |
+
_scriptable: true,
|
9297 |
+
_indexable: (name) => name !== 'borderDash' && name !== 'fill',
|
9298 |
+
};
|
9299 |
+
|
9300 |
+
function inRange$1(el, pos, axis, useFinalPosition) {
|
9301 |
+
const options = el.options;
|
9302 |
+
const {[axis]: value} = el.getProps([axis], useFinalPosition);
|
9303 |
+
return (Math.abs(pos - value) < options.radius + options.hitRadius);
|
9304 |
+
}
|
9305 |
+
class PointElement extends Element {
|
9306 |
+
constructor(cfg) {
|
9307 |
+
super();
|
9308 |
+
this.options = undefined;
|
9309 |
+
this.parsed = undefined;
|
9310 |
+
this.skip = undefined;
|
9311 |
+
this.stop = undefined;
|
9312 |
+
if (cfg) {
|
9313 |
+
Object.assign(this, cfg);
|
9314 |
+
}
|
9315 |
+
}
|
9316 |
+
inRange(mouseX, mouseY, useFinalPosition) {
|
9317 |
+
const options = this.options;
|
9318 |
+
const {x, y} = this.getProps(['x', 'y'], useFinalPosition);
|
9319 |
+
return ((Math.pow(mouseX - x, 2) + Math.pow(mouseY - y, 2)) < Math.pow(options.hitRadius + options.radius, 2));
|
9320 |
+
}
|
9321 |
+
inXRange(mouseX, useFinalPosition) {
|
9322 |
+
return inRange$1(this, mouseX, 'x', useFinalPosition);
|
9323 |
+
}
|
9324 |
+
inYRange(mouseY, useFinalPosition) {
|
9325 |
+
return inRange$1(this, mouseY, 'y', useFinalPosition);
|
9326 |
+
}
|
9327 |
+
getCenterPoint(useFinalPosition) {
|
9328 |
+
const {x, y} = this.getProps(['x', 'y'], useFinalPosition);
|
9329 |
+
return {x, y};
|
9330 |
+
}
|
9331 |
+
size(options) {
|
9332 |
+
options = options || this.options || {};
|
9333 |
+
let radius = options.radius || 0;
|
9334 |
+
radius = Math.max(radius, radius && options.hoverRadius || 0);
|
9335 |
+
const borderWidth = radius && options.borderWidth || 0;
|
9336 |
+
return (radius + borderWidth) * 2;
|
9337 |
+
}
|
9338 |
+
draw(ctx, area) {
|
9339 |
+
const options = this.options;
|
9340 |
+
if (this.skip || options.radius < 0.1 || !_isPointInArea(this, area, this.size(options) / 2)) {
|
9341 |
+
return;
|
9342 |
+
}
|
9343 |
+
ctx.strokeStyle = options.borderColor;
|
9344 |
+
ctx.lineWidth = options.borderWidth;
|
9345 |
+
ctx.fillStyle = options.backgroundColor;
|
9346 |
+
drawPoint(ctx, options, this.x, this.y);
|
9347 |
+
}
|
9348 |
+
getRange() {
|
9349 |
+
const options = this.options || {};
|
9350 |
+
return options.radius + options.hitRadius;
|
9351 |
+
}
|
9352 |
+
}
|
9353 |
+
PointElement.id = 'point';
|
9354 |
+
PointElement.defaults = {
|
9355 |
+
borderWidth: 1,
|
9356 |
+
hitRadius: 1,
|
9357 |
+
hoverBorderWidth: 1,
|
9358 |
+
hoverRadius: 4,
|
9359 |
+
pointStyle: 'circle',
|
9360 |
+
radius: 3,
|
9361 |
+
rotation: 0
|
9362 |
+
};
|
9363 |
+
PointElement.defaultRoutes = {
|
9364 |
+
backgroundColor: 'backgroundColor',
|
9365 |
+
borderColor: 'borderColor'
|
9366 |
+
};
|
9367 |
+
|
9368 |
+
function getBarBounds(bar, useFinalPosition) {
|
9369 |
+
const {x, y, base, width, height} = bar.getProps(['x', 'y', 'base', 'width', 'height'], useFinalPosition);
|
9370 |
+
let left, right, top, bottom, half;
|
9371 |
+
if (bar.horizontal) {
|
9372 |
+
half = height / 2;
|
9373 |
+
left = Math.min(x, base);
|
9374 |
+
right = Math.max(x, base);
|
9375 |
+
top = y - half;
|
9376 |
+
bottom = y + half;
|
9377 |
+
} else {
|
9378 |
+
half = width / 2;
|
9379 |
+
left = x - half;
|
9380 |
+
right = x + half;
|
9381 |
+
top = Math.min(y, base);
|
9382 |
+
bottom = Math.max(y, base);
|
9383 |
+
}
|
9384 |
+
return {left, top, right, bottom};
|
9385 |
+
}
|
9386 |
+
function skipOrLimit(skip, value, min, max) {
|
9387 |
+
return skip ? 0 : _limitValue(value, min, max);
|
9388 |
+
}
|
9389 |
+
function parseBorderWidth(bar, maxW, maxH) {
|
9390 |
+
const value = bar.options.borderWidth;
|
9391 |
+
const skip = bar.borderSkipped;
|
9392 |
+
const o = toTRBL(value);
|
9393 |
+
return {
|
9394 |
+
t: skipOrLimit(skip.top, o.top, 0, maxH),
|
9395 |
+
r: skipOrLimit(skip.right, o.right, 0, maxW),
|
9396 |
+
b: skipOrLimit(skip.bottom, o.bottom, 0, maxH),
|
9397 |
+
l: skipOrLimit(skip.left, o.left, 0, maxW)
|
9398 |
+
};
|
9399 |
+
}
|
9400 |
+
function parseBorderRadius(bar, maxW, maxH) {
|
9401 |
+
const {enableBorderRadius} = bar.getProps(['enableBorderRadius']);
|
9402 |
+
const value = bar.options.borderRadius;
|
9403 |
+
const o = toTRBLCorners(value);
|
9404 |
+
const maxR = Math.min(maxW, maxH);
|
9405 |
+
const skip = bar.borderSkipped;
|
9406 |
+
const enableBorder = enableBorderRadius || isObject(value);
|
9407 |
+
return {
|
9408 |
+
topLeft: skipOrLimit(!enableBorder || skip.top || skip.left, o.topLeft, 0, maxR),
|
9409 |
+
topRight: skipOrLimit(!enableBorder || skip.top || skip.right, o.topRight, 0, maxR),
|
9410 |
+
bottomLeft: skipOrLimit(!enableBorder || skip.bottom || skip.left, o.bottomLeft, 0, maxR),
|
9411 |
+
bottomRight: skipOrLimit(!enableBorder || skip.bottom || skip.right, o.bottomRight, 0, maxR)
|
9412 |
+
};
|
9413 |
+
}
|
9414 |
+
function boundingRects(bar) {
|
9415 |
+
const bounds = getBarBounds(bar);
|
9416 |
+
const width = bounds.right - bounds.left;
|
9417 |
+
const height = bounds.bottom - bounds.top;
|
9418 |
+
const border = parseBorderWidth(bar, width / 2, height / 2);
|
9419 |
+
const radius = parseBorderRadius(bar, width / 2, height / 2);
|
9420 |
+
return {
|
9421 |
+
outer: {
|
9422 |
+
x: bounds.left,
|
9423 |
+
y: bounds.top,
|
9424 |
+
w: width,
|
9425 |
+
h: height,
|
9426 |
+
radius
|
9427 |
+
},
|
9428 |
+
inner: {
|
9429 |
+
x: bounds.left + border.l,
|
9430 |
+
y: bounds.top + border.t,
|
9431 |
+
w: width - border.l - border.r,
|
9432 |
+
h: height - border.t - border.b,
|
9433 |
+
radius: {
|
9434 |
+
topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),
|
9435 |
+
topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),
|
9436 |
+
bottomLeft: Math.max(0, radius.bottomLeft - Math.max(border.b, border.l)),
|
9437 |
+
bottomRight: Math.max(0, radius.bottomRight - Math.max(border.b, border.r)),
|
9438 |
+
}
|
9439 |
+
}
|
9440 |
+
};
|
9441 |
+
}
|
9442 |
+
function inRange(bar, x, y, useFinalPosition) {
|
9443 |
+
const skipX = x === null;
|
9444 |
+
const skipY = y === null;
|
9445 |
+
const skipBoth = skipX && skipY;
|
9446 |
+
const bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition);
|
9447 |
+
return bounds
|
9448 |
+
&& (skipX || _isBetween(x, bounds.left, bounds.right))
|
9449 |
+
&& (skipY || _isBetween(y, bounds.top, bounds.bottom));
|
9450 |
+
}
|
9451 |
+
function hasRadius(radius) {
|
9452 |
+
return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight;
|
9453 |
+
}
|
9454 |
+
function addNormalRectPath(ctx, rect) {
|
9455 |
+
ctx.rect(rect.x, rect.y, rect.w, rect.h);
|
9456 |
+
}
|
9457 |
+
function inflateRect(rect, amount, refRect = {}) {
|
9458 |
+
const x = rect.x !== refRect.x ? -amount : 0;
|
9459 |
+
const y = rect.y !== refRect.y ? -amount : 0;
|
9460 |
+
const w = (rect.x + rect.w !== refRect.x + refRect.w ? amount : 0) - x;
|
9461 |
+
const h = (rect.y + rect.h !== refRect.y + refRect.h ? amount : 0) - y;
|
9462 |
+
return {
|
9463 |
+
x: rect.x + x,
|
9464 |
+
y: rect.y + y,
|
9465 |
+
w: rect.w + w,
|
9466 |
+
h: rect.h + h,
|
9467 |
+
radius: rect.radius
|
9468 |
+
};
|
9469 |
+
}
|
9470 |
+
class BarElement extends Element {
|
9471 |
+
constructor(cfg) {
|
9472 |
+
super();
|
9473 |
+
this.options = undefined;
|
9474 |
+
this.horizontal = undefined;
|
9475 |
+
this.base = undefined;
|
9476 |
+
this.width = undefined;
|
9477 |
+
this.height = undefined;
|
9478 |
+
this.inflateAmount = undefined;
|
9479 |
+
if (cfg) {
|
9480 |
+
Object.assign(this, cfg);
|
9481 |
+
}
|
9482 |
+
}
|
9483 |
+
draw(ctx) {
|
9484 |
+
const {inflateAmount, options: {borderColor, backgroundColor}} = this;
|
9485 |
+
const {inner, outer} = boundingRects(this);
|
9486 |
+
const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;
|
9487 |
+
ctx.save();
|
9488 |
+
if (outer.w !== inner.w || outer.h !== inner.h) {
|
9489 |
+
ctx.beginPath();
|
9490 |
+
addRectPath(ctx, inflateRect(outer, inflateAmount, inner));
|
9491 |
+
ctx.clip();
|
9492 |
+
addRectPath(ctx, inflateRect(inner, -inflateAmount, outer));
|
9493 |
+
ctx.fillStyle = borderColor;
|
9494 |
+
ctx.fill('evenodd');
|
9495 |
+
}
|
9496 |
+
ctx.beginPath();
|
9497 |
+
addRectPath(ctx, inflateRect(inner, inflateAmount));
|
9498 |
+
ctx.fillStyle = backgroundColor;
|
9499 |
+
ctx.fill();
|
9500 |
+
ctx.restore();
|
9501 |
+
}
|
9502 |
+
inRange(mouseX, mouseY, useFinalPosition) {
|
9503 |
+
return inRange(this, mouseX, mouseY, useFinalPosition);
|
9504 |
+
}
|
9505 |
+
inXRange(mouseX, useFinalPosition) {
|
9506 |
+
return inRange(this, mouseX, null, useFinalPosition);
|
9507 |
+
}
|
9508 |
+
inYRange(mouseY, useFinalPosition) {
|
9509 |
+
return inRange(this, null, mouseY, useFinalPosition);
|
9510 |
+
}
|
9511 |
+
getCenterPoint(useFinalPosition) {
|
9512 |
+
const {x, y, base, horizontal} = this.getProps(['x', 'y', 'base', 'horizontal'], useFinalPosition);
|
9513 |
+
return {
|
9514 |
+
x: horizontal ? (x + base) / 2 : x,
|
9515 |
+
y: horizontal ? y : (y + base) / 2
|
9516 |
+
};
|
9517 |
+
}
|
9518 |
+
getRange(axis) {
|
9519 |
+
return axis === 'x' ? this.width / 2 : this.height / 2;
|
9520 |
+
}
|
9521 |
+
}
|
9522 |
+
BarElement.id = 'bar';
|
9523 |
+
BarElement.defaults = {
|
9524 |
+
borderSkipped: 'start',
|
9525 |
+
borderWidth: 0,
|
9526 |
+
borderRadius: 0,
|
9527 |
+
inflateAmount: 'auto',
|
9528 |
+
pointStyle: undefined
|
9529 |
+
};
|
9530 |
+
BarElement.defaultRoutes = {
|
9531 |
+
backgroundColor: 'backgroundColor',
|
9532 |
+
borderColor: 'borderColor'
|
9533 |
+
};
|
9534 |
+
|
9535 |
+
var elements = /*#__PURE__*/Object.freeze({
|
9536 |
+
__proto__: null,
|
9537 |
+
ArcElement: ArcElement,
|
9538 |
+
LineElement: LineElement,
|
9539 |
+
PointElement: PointElement,
|
9540 |
+
BarElement: BarElement
|
9541 |
+
});
|
9542 |
+
|
9543 |
+
function lttbDecimation(data, start, count, availableWidth, options) {
|
9544 |
+
const samples = options.samples || availableWidth;
|
9545 |
+
if (samples >= count) {
|
9546 |
+
return data.slice(start, start + count);
|
9547 |
+
}
|
9548 |
+
const decimated = [];
|
9549 |
+
const bucketWidth = (count - 2) / (samples - 2);
|
9550 |
+
let sampledIndex = 0;
|
9551 |
+
const endIndex = start + count - 1;
|
9552 |
+
let a = start;
|
9553 |
+
let i, maxAreaPoint, maxArea, area, nextA;
|
9554 |
+
decimated[sampledIndex++] = data[a];
|
9555 |
+
for (i = 0; i < samples - 2; i++) {
|
9556 |
+
let avgX = 0;
|
9557 |
+
let avgY = 0;
|
9558 |
+
let j;
|
9559 |
+
const avgRangeStart = Math.floor((i + 1) * bucketWidth) + 1 + start;
|
9560 |
+
const avgRangeEnd = Math.min(Math.floor((i + 2) * bucketWidth) + 1, count) + start;
|
9561 |
+
const avgRangeLength = avgRangeEnd - avgRangeStart;
|
9562 |
+
for (j = avgRangeStart; j < avgRangeEnd; j++) {
|
9563 |
+
avgX += data[j].x;
|
9564 |
+
avgY += data[j].y;
|
9565 |
+
}
|
9566 |
+
avgX /= avgRangeLength;
|
9567 |
+
avgY /= avgRangeLength;
|
9568 |
+
const rangeOffs = Math.floor(i * bucketWidth) + 1 + start;
|
9569 |
+
const rangeTo = Math.min(Math.floor((i + 1) * bucketWidth) + 1, count) + start;
|
9570 |
+
const {x: pointAx, y: pointAy} = data[a];
|
9571 |
+
maxArea = area = -1;
|
9572 |
+
for (j = rangeOffs; j < rangeTo; j++) {
|
9573 |
+
area = 0.5 * Math.abs(
|
9574 |
+
(pointAx - avgX) * (data[j].y - pointAy) -
|
9575 |
+
(pointAx - data[j].x) * (avgY - pointAy)
|
9576 |
+
);
|
9577 |
+
if (area > maxArea) {
|
9578 |
+
maxArea = area;
|
9579 |
+
maxAreaPoint = data[j];
|
9580 |
+
nextA = j;
|
9581 |
+
}
|
9582 |
+
}
|
9583 |
+
decimated[sampledIndex++] = maxAreaPoint;
|
9584 |
+
a = nextA;
|
9585 |
+
}
|
9586 |
+
decimated[sampledIndex++] = data[endIndex];
|
9587 |
+
return decimated;
|
9588 |
+
}
|
9589 |
+
function minMaxDecimation(data, start, count, availableWidth) {
|
9590 |
+
let avgX = 0;
|
9591 |
+
let countX = 0;
|
9592 |
+
let i, point, x, y, prevX, minIndex, maxIndex, startIndex, minY, maxY;
|
9593 |
+
const decimated = [];
|
9594 |
+
const endIndex = start + count - 1;
|
9595 |
+
const xMin = data[start].x;
|
9596 |
+
const xMax = data[endIndex].x;
|
9597 |
+
const dx = xMax - xMin;
|
9598 |
+
for (i = start; i < start + count; ++i) {
|
9599 |
+
point = data[i];
|
9600 |
+
x = (point.x - xMin) / dx * availableWidth;
|
9601 |
+
y = point.y;
|
9602 |
+
const truncX = x | 0;
|
9603 |
+
if (truncX === prevX) {
|
9604 |
+
if (y < minY) {
|
9605 |
+
minY = y;
|
9606 |
+
minIndex = i;
|
9607 |
+
} else if (y > maxY) {
|
9608 |
+
maxY = y;
|
9609 |
+
maxIndex = i;
|
9610 |
+
}
|
9611 |
+
avgX = (countX * avgX + point.x) / ++countX;
|
9612 |
+
} else {
|
9613 |
+
const lastIndex = i - 1;
|
9614 |
+
if (!isNullOrUndef(minIndex) && !isNullOrUndef(maxIndex)) {
|
9615 |
+
const intermediateIndex1 = Math.min(minIndex, maxIndex);
|
9616 |
+
const intermediateIndex2 = Math.max(minIndex, maxIndex);
|
9617 |
+
if (intermediateIndex1 !== startIndex && intermediateIndex1 !== lastIndex) {
|
9618 |
+
decimated.push({
|
9619 |
+
...data[intermediateIndex1],
|
9620 |
+
x: avgX,
|
9621 |
+
});
|
9622 |
+
}
|
9623 |
+
if (intermediateIndex2 !== startIndex && intermediateIndex2 !== lastIndex) {
|
9624 |
+
decimated.push({
|
9625 |
+
...data[intermediateIndex2],
|
9626 |
+
x: avgX
|
9627 |
+
});
|
9628 |
+
}
|
9629 |
+
}
|
9630 |
+
if (i > 0 && lastIndex !== startIndex) {
|
9631 |
+
decimated.push(data[lastIndex]);
|
9632 |
+
}
|
9633 |
+
decimated.push(point);
|
9634 |
+
prevX = truncX;
|
9635 |
+
countX = 0;
|
9636 |
+
minY = maxY = y;
|
9637 |
+
minIndex = maxIndex = startIndex = i;
|
9638 |
+
}
|
9639 |
+
}
|
9640 |
+
return decimated;
|
9641 |
+
}
|
9642 |
+
function cleanDecimatedDataset(dataset) {
|
9643 |
+
if (dataset._decimated) {
|
9644 |
+
const data = dataset._data;
|
9645 |
+
delete dataset._decimated;
|
9646 |
+
delete dataset._data;
|
9647 |
+
Object.defineProperty(dataset, 'data', {value: data});
|
9648 |
+
}
|
9649 |
+
}
|
9650 |
+
function cleanDecimatedData(chart) {
|
9651 |
+
chart.data.datasets.forEach((dataset) => {
|
9652 |
+
cleanDecimatedDataset(dataset);
|
9653 |
+
});
|
9654 |
+
}
|
9655 |
+
function getStartAndCountOfVisiblePointsSimplified(meta, points) {
|
9656 |
+
const pointCount = points.length;
|
9657 |
+
let start = 0;
|
9658 |
+
let count;
|
9659 |
+
const {iScale} = meta;
|
9660 |
+
const {min, max, minDefined, maxDefined} = iScale.getUserBounds();
|
9661 |
+
if (minDefined) {
|
9662 |
+
start = _limitValue(_lookupByKey(points, iScale.axis, min).lo, 0, pointCount - 1);
|
9663 |
+
}
|
9664 |
+
if (maxDefined) {
|
9665 |
+
count = _limitValue(_lookupByKey(points, iScale.axis, max).hi + 1, start, pointCount) - start;
|
9666 |
+
} else {
|
9667 |
+
count = pointCount - start;
|
9668 |
+
}
|
9669 |
+
return {start, count};
|
9670 |
+
}
|
9671 |
+
var plugin_decimation = {
|
9672 |
+
id: 'decimation',
|
9673 |
+
defaults: {
|
9674 |
+
algorithm: 'min-max',
|
9675 |
+
enabled: false,
|
9676 |
+
},
|
9677 |
+
beforeElementsUpdate: (chart, args, options) => {
|
9678 |
+
if (!options.enabled) {
|
9679 |
+
cleanDecimatedData(chart);
|
9680 |
+
return;
|
9681 |
+
}
|
9682 |
+
const availableWidth = chart.width;
|
9683 |
+
chart.data.datasets.forEach((dataset, datasetIndex) => {
|
9684 |
+
const {_data, indexAxis} = dataset;
|
9685 |
+
const meta = chart.getDatasetMeta(datasetIndex);
|
9686 |
+
const data = _data || dataset.data;
|
9687 |
+
if (resolve([indexAxis, chart.options.indexAxis]) === 'y') {
|
9688 |
+
return;
|
9689 |
+
}
|
9690 |
+
if (meta.type !== 'line') {
|
9691 |
+
return;
|
9692 |
+
}
|
9693 |
+
const xAxis = chart.scales[meta.xAxisID];
|
9694 |
+
if (xAxis.type !== 'linear' && xAxis.type !== 'time') {
|
9695 |
+
return;
|
9696 |
+
}
|
9697 |
+
if (chart.options.parsing) {
|
9698 |
+
return;
|
9699 |
+
}
|
9700 |
+
let {start, count} = getStartAndCountOfVisiblePointsSimplified(meta, data);
|
9701 |
+
const threshold = options.threshold || 4 * availableWidth;
|
9702 |
+
if (count <= threshold) {
|
9703 |
+
cleanDecimatedDataset(dataset);
|
9704 |
+
return;
|
9705 |
+
}
|
9706 |
+
if (isNullOrUndef(_data)) {
|
9707 |
+
dataset._data = data;
|
9708 |
+
delete dataset.data;
|
9709 |
+
Object.defineProperty(dataset, 'data', {
|
9710 |
+
configurable: true,
|
9711 |
+
enumerable: true,
|
9712 |
+
get: function() {
|
9713 |
+
return this._decimated;
|
9714 |
+
},
|
9715 |
+
set: function(d) {
|
9716 |
+
this._data = d;
|
9717 |
+
}
|
9718 |
+
});
|
9719 |
+
}
|
9720 |
+
let decimated;
|
9721 |
+
switch (options.algorithm) {
|
9722 |
+
case 'lttb':
|
9723 |
+
decimated = lttbDecimation(data, start, count, availableWidth, options);
|
9724 |
+
break;
|
9725 |
+
case 'min-max':
|
9726 |
+
decimated = minMaxDecimation(data, start, count, availableWidth);
|
9727 |
+
break;
|
9728 |
+
default:
|
9729 |
+
throw new Error(`Unsupported decimation algorithm '${options.algorithm}'`);
|
9730 |
+
}
|
9731 |
+
dataset._decimated = decimated;
|
9732 |
+
});
|
9733 |
+
},
|
9734 |
+
destroy(chart) {
|
9735 |
+
cleanDecimatedData(chart);
|
9736 |
+
}
|
9737 |
+
};
|
9738 |
+
|
9739 |
+
function getLineByIndex(chart, index) {
|
9740 |
+
const meta = chart.getDatasetMeta(index);
|
9741 |
+
const visible = meta && chart.isDatasetVisible(index);
|
9742 |
+
return visible ? meta.dataset : null;
|
9743 |
+
}
|
9744 |
+
function parseFillOption(line) {
|
9745 |
+
const options = line.options;
|
9746 |
+
const fillOption = options.fill;
|
9747 |
+
let fill = valueOrDefault(fillOption && fillOption.target, fillOption);
|
9748 |
+
if (fill === undefined) {
|
9749 |
+
fill = !!options.backgroundColor;
|
9750 |
+
}
|
9751 |
+
if (fill === false || fill === null) {
|
9752 |
+
return false;
|
9753 |
+
}
|
9754 |
+
if (fill === true) {
|
9755 |
+
return 'origin';
|
9756 |
+
}
|
9757 |
+
return fill;
|
9758 |
+
}
|
9759 |
+
function decodeFill(line, index, count) {
|
9760 |
+
const fill = parseFillOption(line);
|
9761 |
+
if (isObject(fill)) {
|
9762 |
+
return isNaN(fill.value) ? false : fill;
|
9763 |
+
}
|
9764 |
+
let target = parseFloat(fill);
|
9765 |
+
if (isNumberFinite(target) && Math.floor(target) === target) {
|
9766 |
+
if (fill[0] === '-' || fill[0] === '+') {
|
9767 |
+
target = index + target;
|
9768 |
+
}
|
9769 |
+
if (target === index || target < 0 || target >= count) {
|
9770 |
+
return false;
|
9771 |
+
}
|
9772 |
+
return target;
|
9773 |
+
}
|
9774 |
+
return ['origin', 'start', 'end', 'stack', 'shape'].indexOf(fill) >= 0 && fill;
|
9775 |
+
}
|
9776 |
+
function computeLinearBoundary(source) {
|
9777 |
+
const {scale = {}, fill} = source;
|
9778 |
+
let target = null;
|
9779 |
+
let horizontal;
|
9780 |
+
if (fill === 'start') {
|
9781 |
+
target = scale.bottom;
|
9782 |
+
} else if (fill === 'end') {
|
9783 |
+
target = scale.top;
|
9784 |
+
} else if (isObject(fill)) {
|
9785 |
+
target = scale.getPixelForValue(fill.value);
|
9786 |
+
} else if (scale.getBasePixel) {
|
9787 |
+
target = scale.getBasePixel();
|
9788 |
+
}
|
9789 |
+
if (isNumberFinite(target)) {
|
9790 |
+
horizontal = scale.isHorizontal();
|
9791 |
+
return {
|
9792 |
+
x: horizontal ? target : null,
|
9793 |
+
y: horizontal ? null : target
|
9794 |
+
};
|
9795 |
+
}
|
9796 |
+
return null;
|
9797 |
+
}
|
9798 |
+
class simpleArc {
|
9799 |
+
constructor(opts) {
|
9800 |
+
this.x = opts.x;
|
9801 |
+
this.y = opts.y;
|
9802 |
+
this.radius = opts.radius;
|
9803 |
+
}
|
9804 |
+
pathSegment(ctx, bounds, opts) {
|
9805 |
+
const {x, y, radius} = this;
|
9806 |
+
bounds = bounds || {start: 0, end: TAU};
|
9807 |
+
ctx.arc(x, y, radius, bounds.end, bounds.start, true);
|
9808 |
+
return !opts.bounds;
|
9809 |
+
}
|
9810 |
+
interpolate(point) {
|
9811 |
+
const {x, y, radius} = this;
|
9812 |
+
const angle = point.angle;
|
9813 |
+
return {
|
9814 |
+
x: x + Math.cos(angle) * radius,
|
9815 |
+
y: y + Math.sin(angle) * radius,
|
9816 |
+
angle
|
9817 |
+
};
|
9818 |
+
}
|
9819 |
+
}
|
9820 |
+
function computeCircularBoundary(source) {
|
9821 |
+
const {scale, fill} = source;
|
9822 |
+
const options = scale.options;
|
9823 |
+
const length = scale.getLabels().length;
|
9824 |
+
const target = [];
|
9825 |
+
const start = options.reverse ? scale.max : scale.min;
|
9826 |
+
const end = options.reverse ? scale.min : scale.max;
|
9827 |
+
let i, center, value;
|
9828 |
+
if (fill === 'start') {
|
9829 |
+
value = start;
|
9830 |
+
} else if (fill === 'end') {
|
9831 |
+
value = end;
|
9832 |
+
} else if (isObject(fill)) {
|
9833 |
+
value = fill.value;
|
9834 |
+
} else {
|
9835 |
+
value = scale.getBaseValue();
|
9836 |
+
}
|
9837 |
+
if (options.grid.circular) {
|
9838 |
+
center = scale.getPointPositionForValue(0, start);
|
9839 |
+
return new simpleArc({
|
9840 |
+
x: center.x,
|
9841 |
+
y: center.y,
|
9842 |
+
radius: scale.getDistanceFromCenterForValue(value)
|
9843 |
+
});
|
9844 |
+
}
|
9845 |
+
for (i = 0; i < length; ++i) {
|
9846 |
+
target.push(scale.getPointPositionForValue(i, value));
|
9847 |
+
}
|
9848 |
+
return target;
|
9849 |
+
}
|
9850 |
+
function computeBoundary(source) {
|
9851 |
+
const scale = source.scale || {};
|
9852 |
+
if (scale.getPointPositionForValue) {
|
9853 |
+
return computeCircularBoundary(source);
|
9854 |
+
}
|
9855 |
+
return computeLinearBoundary(source);
|
9856 |
+
}
|
9857 |
+
function findSegmentEnd(start, end, points) {
|
9858 |
+
for (;end > start; end--) {
|
9859 |
+
const point = points[end];
|
9860 |
+
if (!isNaN(point.x) && !isNaN(point.y)) {
|
9861 |
+
break;
|
9862 |
+
}
|
9863 |
+
}
|
9864 |
+
return end;
|
9865 |
+
}
|
9866 |
+
function pointsFromSegments(boundary, line) {
|
9867 |
+
const {x = null, y = null} = boundary || {};
|
9868 |
+
const linePoints = line.points;
|
9869 |
+
const points = [];
|
9870 |
+
line.segments.forEach(({start, end}) => {
|
9871 |
+
end = findSegmentEnd(start, end, linePoints);
|
9872 |
+
const first = linePoints[start];
|
9873 |
+
const last = linePoints[end];
|
9874 |
+
if (y !== null) {
|
9875 |
+
points.push({x: first.x, y});
|
9876 |
+
points.push({x: last.x, y});
|
9877 |
+
} else if (x !== null) {
|
9878 |
+
points.push({x, y: first.y});
|
9879 |
+
points.push({x, y: last.y});
|
9880 |
+
}
|
9881 |
+
});
|
9882 |
+
return points;
|
9883 |
+
}
|
9884 |
+
function buildStackLine(source) {
|
9885 |
+
const {scale, index, line} = source;
|
9886 |
+
const points = [];
|
9887 |
+
const segments = line.segments;
|
9888 |
+
const sourcePoints = line.points;
|
9889 |
+
const linesBelow = getLinesBelow(scale, index);
|
9890 |
+
linesBelow.push(createBoundaryLine({x: null, y: scale.bottom}, line));
|
9891 |
+
for (let i = 0; i < segments.length; i++) {
|
9892 |
+
const segment = segments[i];
|
9893 |
+
for (let j = segment.start; j <= segment.end; j++) {
|
9894 |
+
addPointsBelow(points, sourcePoints[j], linesBelow);
|
9895 |
+
}
|
9896 |
+
}
|
9897 |
+
return new LineElement({points, options: {}});
|
9898 |
+
}
|
9899 |
+
function getLinesBelow(scale, index) {
|
9900 |
+
const below = [];
|
9901 |
+
const metas = scale.getMatchingVisibleMetas('line');
|
9902 |
+
for (let i = 0; i < metas.length; i++) {
|
9903 |
+
const meta = metas[i];
|
9904 |
+
if (meta.index === index) {
|
9905 |
+
break;
|
9906 |
+
}
|
9907 |
+
if (!meta.hidden) {
|
9908 |
+
below.unshift(meta.dataset);
|
9909 |
+
}
|
9910 |
+
}
|
9911 |
+
return below;
|
9912 |
+
}
|
9913 |
+
function addPointsBelow(points, sourcePoint, linesBelow) {
|
9914 |
+
const postponed = [];
|
9915 |
+
for (let j = 0; j < linesBelow.length; j++) {
|
9916 |
+
const line = linesBelow[j];
|
9917 |
+
const {first, last, point} = findPoint(line, sourcePoint, 'x');
|
9918 |
+
if (!point || (first && last)) {
|
9919 |
+
continue;
|
9920 |
+
}
|
9921 |
+
if (first) {
|
9922 |
+
postponed.unshift(point);
|
9923 |
+
} else {
|
9924 |
+
points.push(point);
|
9925 |
+
if (!last) {
|
9926 |
+
break;
|
9927 |
+
}
|
9928 |
+
}
|
9929 |
+
}
|
9930 |
+
points.push(...postponed);
|
9931 |
+
}
|
9932 |
+
function findPoint(line, sourcePoint, property) {
|
9933 |
+
const point = line.interpolate(sourcePoint, property);
|
9934 |
+
if (!point) {
|
9935 |
+
return {};
|
9936 |
+
}
|
9937 |
+
const pointValue = point[property];
|
9938 |
+
const segments = line.segments;
|
9939 |
+
const linePoints = line.points;
|
9940 |
+
let first = false;
|
9941 |
+
let last = false;
|
9942 |
+
for (let i = 0; i < segments.length; i++) {
|
9943 |
+
const segment = segments[i];
|
9944 |
+
const firstValue = linePoints[segment.start][property];
|
9945 |
+
const lastValue = linePoints[segment.end][property];
|
9946 |
+
if (_isBetween(pointValue, firstValue, lastValue)) {
|
9947 |
+
first = pointValue === firstValue;
|
9948 |
+
last = pointValue === lastValue;
|
9949 |
+
break;
|
9950 |
+
}
|
9951 |
+
}
|
9952 |
+
return {first, last, point};
|
9953 |
+
}
|
9954 |
+
function getTarget(source) {
|
9955 |
+
const {chart, fill, line} = source;
|
9956 |
+
if (isNumberFinite(fill)) {
|
9957 |
+
return getLineByIndex(chart, fill);
|
9958 |
+
}
|
9959 |
+
if (fill === 'stack') {
|
9960 |
+
return buildStackLine(source);
|
9961 |
+
}
|
9962 |
+
if (fill === 'shape') {
|
9963 |
+
return true;
|
9964 |
+
}
|
9965 |
+
const boundary = computeBoundary(source);
|
9966 |
+
if (boundary instanceof simpleArc) {
|
9967 |
+
return boundary;
|
9968 |
+
}
|
9969 |
+
return createBoundaryLine(boundary, line);
|
9970 |
+
}
|
9971 |
+
function createBoundaryLine(boundary, line) {
|
9972 |
+
let points = [];
|
9973 |
+
let _loop = false;
|
9974 |
+
if (isArray(boundary)) {
|
9975 |
+
_loop = true;
|
9976 |
+
points = boundary;
|
9977 |
+
} else {
|
9978 |
+
points = pointsFromSegments(boundary, line);
|
9979 |
+
}
|
9980 |
+
return points.length ? new LineElement({
|
9981 |
+
points,
|
9982 |
+
options: {tension: 0},
|
9983 |
+
_loop,
|
9984 |
+
_fullLoop: _loop
|
9985 |
+
}) : null;
|
9986 |
+
}
|
9987 |
+
function resolveTarget(sources, index, propagate) {
|
9988 |
+
const source = sources[index];
|
9989 |
+
let fill = source.fill;
|
9990 |
+
const visited = [index];
|
9991 |
+
let target;
|
9992 |
+
if (!propagate) {
|
9993 |
+
return fill;
|
9994 |
+
}
|
9995 |
+
while (fill !== false && visited.indexOf(fill) === -1) {
|
9996 |
+
if (!isNumberFinite(fill)) {
|
9997 |
+
return fill;
|
9998 |
+
}
|
9999 |
+
target = sources[fill];
|
10000 |
+
if (!target) {
|
10001 |
+
return false;
|
10002 |
+
}
|
10003 |
+
if (target.visible) {
|
10004 |
+
return fill;
|
10005 |
+
}
|
10006 |
+
visited.push(fill);
|
10007 |
+
fill = target.fill;
|
10008 |
+
}
|
10009 |
+
return false;
|
10010 |
+
}
|
10011 |
+
function _clip(ctx, target, clipY) {
|
10012 |
+
const {segments, points} = target;
|
10013 |
+
let first = true;
|
10014 |
+
let lineLoop = false;
|
10015 |
+
ctx.beginPath();
|
10016 |
+
for (const segment of segments) {
|
10017 |
+
const {start, end} = segment;
|
10018 |
+
const firstPoint = points[start];
|
10019 |
+
const lastPoint = points[findSegmentEnd(start, end, points)];
|
10020 |
+
if (first) {
|
10021 |
+
ctx.moveTo(firstPoint.x, firstPoint.y);
|
10022 |
+
first = false;
|
10023 |
+
} else {
|
10024 |
+
ctx.lineTo(firstPoint.x, clipY);
|
10025 |
+
ctx.lineTo(firstPoint.x, firstPoint.y);
|
10026 |
+
}
|
10027 |
+
lineLoop = !!target.pathSegment(ctx, segment, {move: lineLoop});
|
10028 |
+
if (lineLoop) {
|
10029 |
+
ctx.closePath();
|
10030 |
+
} else {
|
10031 |
+
ctx.lineTo(lastPoint.x, clipY);
|
10032 |
+
}
|
10033 |
+
}
|
10034 |
+
ctx.lineTo(target.first().x, clipY);
|
10035 |
+
ctx.closePath();
|
10036 |
+
ctx.clip();
|
10037 |
+
}
|
10038 |
+
function getBounds(property, first, last, loop) {
|
10039 |
+
if (loop) {
|
10040 |
+
return;
|
10041 |
+
}
|
10042 |
+
let start = first[property];
|
10043 |
+
let end = last[property];
|
10044 |
+
if (property === 'angle') {
|
10045 |
+
start = _normalizeAngle(start);
|
10046 |
+
end = _normalizeAngle(end);
|
10047 |
+
}
|
10048 |
+
return {property, start, end};
|
10049 |
+
}
|
10050 |
+
function _getEdge(a, b, prop, fn) {
|
10051 |
+
if (a && b) {
|
10052 |
+
return fn(a[prop], b[prop]);
|
10053 |
+
}
|
10054 |
+
return a ? a[prop] : b ? b[prop] : 0;
|
10055 |
+
}
|
10056 |
+
function _segments(line, target, property) {
|
10057 |
+
const segments = line.segments;
|
10058 |
+
const points = line.points;
|
10059 |
+
const tpoints = target.points;
|
10060 |
+
const parts = [];
|
10061 |
+
for (const segment of segments) {
|
10062 |
+
let {start, end} = segment;
|
10063 |
+
end = findSegmentEnd(start, end, points);
|
10064 |
+
const bounds = getBounds(property, points[start], points[end], segment.loop);
|
10065 |
+
if (!target.segments) {
|
10066 |
+
parts.push({
|
10067 |
+
source: segment,
|
10068 |
+
target: bounds,
|
10069 |
+
start: points[start],
|
10070 |
+
end: points[end]
|
10071 |
+
});
|
10072 |
+
continue;
|
10073 |
+
}
|
10074 |
+
const targetSegments = _boundSegments(target, bounds);
|
10075 |
+
for (const tgt of targetSegments) {
|
10076 |
+
const subBounds = getBounds(property, tpoints[tgt.start], tpoints[tgt.end], tgt.loop);
|
10077 |
+
const fillSources = _boundSegment(segment, points, subBounds);
|
10078 |
+
for (const fillSource of fillSources) {
|
10079 |
+
parts.push({
|
10080 |
+
source: fillSource,
|
10081 |
+
target: tgt,
|
10082 |
+
start: {
|
10083 |
+
[property]: _getEdge(bounds, subBounds, 'start', Math.max)
|
10084 |
+
},
|
10085 |
+
end: {
|
10086 |
+
[property]: _getEdge(bounds, subBounds, 'end', Math.min)
|
10087 |
+
}
|
10088 |
+
});
|
10089 |
+
}
|
10090 |
+
}
|
10091 |
+
}
|
10092 |
+
return parts;
|
10093 |
+
}
|
10094 |
+
function clipBounds(ctx, scale, bounds) {
|
10095 |
+
const {top, bottom} = scale.chart.chartArea;
|
10096 |
+
const {property, start, end} = bounds || {};
|
10097 |
+
if (property === 'x') {
|
10098 |
+
ctx.beginPath();
|
10099 |
+
ctx.rect(start, top, end - start, bottom - top);
|
10100 |
+
ctx.clip();
|
10101 |
+
}
|
10102 |
+
}
|
10103 |
+
function interpolatedLineTo(ctx, target, point, property) {
|
10104 |
+
const interpolatedPoint = target.interpolate(point, property);
|
10105 |
+
if (interpolatedPoint) {
|
10106 |
+
ctx.lineTo(interpolatedPoint.x, interpolatedPoint.y);
|
10107 |
+
}
|
10108 |
+
}
|
10109 |
+
function _fill(ctx, cfg) {
|
10110 |
+
const {line, target, property, color, scale} = cfg;
|
10111 |
+
const segments = _segments(line, target, property);
|
10112 |
+
for (const {source: src, target: tgt, start, end} of segments) {
|
10113 |
+
const {style: {backgroundColor = color} = {}} = src;
|
10114 |
+
const notShape = target !== true;
|
10115 |
+
ctx.save();
|
10116 |
+
ctx.fillStyle = backgroundColor;
|
10117 |
+
clipBounds(ctx, scale, notShape && getBounds(property, start, end));
|
10118 |
+
ctx.beginPath();
|
10119 |
+
const lineLoop = !!line.pathSegment(ctx, src);
|
10120 |
+
let loop;
|
10121 |
+
if (notShape) {
|
10122 |
+
if (lineLoop) {
|
10123 |
+
ctx.closePath();
|
10124 |
+
} else {
|
10125 |
+
interpolatedLineTo(ctx, target, end, property);
|
10126 |
+
}
|
10127 |
+
const targetLoop = !!target.pathSegment(ctx, tgt, {move: lineLoop, reverse: true});
|
10128 |
+
loop = lineLoop && targetLoop;
|
10129 |
+
if (!loop) {
|
10130 |
+
interpolatedLineTo(ctx, target, start, property);
|
10131 |
+
}
|
10132 |
+
}
|
10133 |
+
ctx.closePath();
|
10134 |
+
ctx.fill(loop ? 'evenodd' : 'nonzero');
|
10135 |
+
ctx.restore();
|
10136 |
+
}
|
10137 |
+
}
|
10138 |
+
function doFill(ctx, cfg) {
|
10139 |
+
const {line, target, above, below, area, scale} = cfg;
|
10140 |
+
const property = line._loop ? 'angle' : cfg.axis;
|
10141 |
+
ctx.save();
|
10142 |
+
if (property === 'x' && below !== above) {
|
10143 |
+
_clip(ctx, target, area.top);
|
10144 |
+
_fill(ctx, {line, target, color: above, scale, property});
|
10145 |
+
ctx.restore();
|
10146 |
+
ctx.save();
|
10147 |
+
_clip(ctx, target, area.bottom);
|
10148 |
+
}
|
10149 |
+
_fill(ctx, {line, target, color: below, scale, property});
|
10150 |
+
ctx.restore();
|
10151 |
+
}
|
10152 |
+
function drawfill(ctx, source, area) {
|
10153 |
+
const target = getTarget(source);
|
10154 |
+
const {line, scale, axis} = source;
|
10155 |
+
const lineOpts = line.options;
|
10156 |
+
const fillOption = lineOpts.fill;
|
10157 |
+
const color = lineOpts.backgroundColor;
|
10158 |
+
const {above = color, below = color} = fillOption || {};
|
10159 |
+
if (target && line.points.length) {
|
10160 |
+
clipArea(ctx, area);
|
10161 |
+
doFill(ctx, {line, target, above, below, area, scale, axis});
|
10162 |
+
unclipArea(ctx);
|
10163 |
+
}
|
10164 |
+
}
|
10165 |
+
var plugin_filler = {
|
10166 |
+
id: 'filler',
|
10167 |
+
afterDatasetsUpdate(chart, _args, options) {
|
10168 |
+
const count = (chart.data.datasets || []).length;
|
10169 |
+
const sources = [];
|
10170 |
+
let meta, i, line, source;
|
10171 |
+
for (i = 0; i < count; ++i) {
|
10172 |
+
meta = chart.getDatasetMeta(i);
|
10173 |
+
line = meta.dataset;
|
10174 |
+
source = null;
|
10175 |
+
if (line && line.options && line instanceof LineElement) {
|
10176 |
+
source = {
|
10177 |
+
visible: chart.isDatasetVisible(i),
|
10178 |
+
index: i,
|
10179 |
+
fill: decodeFill(line, i, count),
|
10180 |
+
chart,
|
10181 |
+
axis: meta.controller.options.indexAxis,
|
10182 |
+
scale: meta.vScale,
|
10183 |
+
line,
|
10184 |
+
};
|
10185 |
+
}
|
10186 |
+
meta.$filler = source;
|
10187 |
+
sources.push(source);
|
10188 |
+
}
|
10189 |
+
for (i = 0; i < count; ++i) {
|
10190 |
+
source = sources[i];
|
10191 |
+
if (!source || source.fill === false) {
|
10192 |
+
continue;
|
10193 |
+
}
|
10194 |
+
source.fill = resolveTarget(sources, i, options.propagate);
|
10195 |
+
}
|
10196 |
+
},
|
10197 |
+
beforeDraw(chart, _args, options) {
|
10198 |
+
const draw = options.drawTime === 'beforeDraw';
|
10199 |
+
const metasets = chart.getSortedVisibleDatasetMetas();
|
10200 |
+
const area = chart.chartArea;
|
10201 |
+
for (let i = metasets.length - 1; i >= 0; --i) {
|
10202 |
+
const source = metasets[i].$filler;
|
10203 |
+
if (!source) {
|
10204 |
+
continue;
|
10205 |
+
}
|
10206 |
+
source.line.updateControlPoints(area, source.axis);
|
10207 |
+
if (draw) {
|
10208 |
+
drawfill(chart.ctx, source, area);
|
10209 |
+
}
|
10210 |
+
}
|
10211 |
+
},
|
10212 |
+
beforeDatasetsDraw(chart, _args, options) {
|
10213 |
+
if (options.drawTime !== 'beforeDatasetsDraw') {
|
10214 |
+
return;
|
10215 |
+
}
|
10216 |
+
const metasets = chart.getSortedVisibleDatasetMetas();
|
10217 |
+
for (let i = metasets.length - 1; i >= 0; --i) {
|
10218 |
+
const source = metasets[i].$filler;
|
10219 |
+
if (source) {
|
10220 |
+
drawfill(chart.ctx, source, chart.chartArea);
|
10221 |
+
}
|
10222 |
+
}
|
10223 |
+
},
|
10224 |
+
beforeDatasetDraw(chart, args, options) {
|
10225 |
+
const source = args.meta.$filler;
|
10226 |
+
if (!source || source.fill === false || options.drawTime !== 'beforeDatasetDraw') {
|
10227 |
+
return;
|
10228 |
+
}
|
10229 |
+
drawfill(chart.ctx, source, chart.chartArea);
|
10230 |
+
},
|
10231 |
+
defaults: {
|
10232 |
+
propagate: true,
|
10233 |
+
drawTime: 'beforeDatasetDraw'
|
10234 |
+
}
|
10235 |
+
};
|
10236 |
+
|
10237 |
+
const getBoxSize = (labelOpts, fontSize) => {
|
10238 |
+
let {boxHeight = fontSize, boxWidth = fontSize} = labelOpts;
|
10239 |
+
if (labelOpts.usePointStyle) {
|
10240 |
+
boxHeight = Math.min(boxHeight, fontSize);
|
10241 |
+
boxWidth = Math.min(boxWidth, fontSize);
|
10242 |
+
}
|
10243 |
+
return {
|
10244 |
+
boxWidth,
|
10245 |
+
boxHeight,
|
10246 |
+
itemHeight: Math.max(fontSize, boxHeight)
|
10247 |
+
};
|
10248 |
+
};
|
10249 |
+
const itemsEqual = (a, b) => a !== null && b !== null && a.datasetIndex === b.datasetIndex && a.index === b.index;
|
10250 |
+
class Legend extends Element {
|
10251 |
+
constructor(config) {
|
10252 |
+
super();
|
10253 |
+
this._added = false;
|
10254 |
+
this.legendHitBoxes = [];
|
10255 |
+
this._hoveredItem = null;
|
10256 |
+
this.doughnutMode = false;
|
10257 |
+
this.chart = config.chart;
|
10258 |
+
this.options = config.options;
|
10259 |
+
this.ctx = config.ctx;
|
10260 |
+
this.legendItems = undefined;
|
10261 |
+
this.columnSizes = undefined;
|
10262 |
+
this.lineWidths = undefined;
|
10263 |
+
this.maxHeight = undefined;
|
10264 |
+
this.maxWidth = undefined;
|
10265 |
+
this.top = undefined;
|
10266 |
+
this.bottom = undefined;
|
10267 |
+
this.left = undefined;
|
10268 |
+
this.right = undefined;
|
10269 |
+
this.height = undefined;
|
10270 |
+
this.width = undefined;
|
10271 |
+
this._margins = undefined;
|
10272 |
+
this.position = undefined;
|
10273 |
+
this.weight = undefined;
|
10274 |
+
this.fullSize = undefined;
|
10275 |
+
}
|
10276 |
+
update(maxWidth, maxHeight, margins) {
|
10277 |
+
this.maxWidth = maxWidth;
|
10278 |
+
this.maxHeight = maxHeight;
|
10279 |
+
this._margins = margins;
|
10280 |
+
this.setDimensions();
|
10281 |
+
this.buildLabels();
|
10282 |
+
this.fit();
|
10283 |
+
}
|
10284 |
+
setDimensions() {
|
10285 |
+
if (this.isHorizontal()) {
|
10286 |
+
this.width = this.maxWidth;
|
10287 |
+
this.left = this._margins.left;
|
10288 |
+
this.right = this.width;
|
10289 |
+
} else {
|
10290 |
+
this.height = this.maxHeight;
|
10291 |
+
this.top = this._margins.top;
|
10292 |
+
this.bottom = this.height;
|
10293 |
+
}
|
10294 |
+
}
|
10295 |
+
buildLabels() {
|
10296 |
+
const labelOpts = this.options.labels || {};
|
10297 |
+
let legendItems = callback(labelOpts.generateLabels, [this.chart], this) || [];
|
10298 |
+
if (labelOpts.filter) {
|
10299 |
+
legendItems = legendItems.filter((item) => labelOpts.filter(item, this.chart.data));
|
10300 |
+
}
|
10301 |
+
if (labelOpts.sort) {
|
10302 |
+
legendItems = legendItems.sort((a, b) => labelOpts.sort(a, b, this.chart.data));
|
10303 |
+
}
|
10304 |
+
if (this.options.reverse) {
|
10305 |
+
legendItems.reverse();
|
10306 |
+
}
|
10307 |
+
this.legendItems = legendItems;
|
10308 |
+
}
|
10309 |
+
fit() {
|
10310 |
+
const {options, ctx} = this;
|
10311 |
+
if (!options.display) {
|
10312 |
+
this.width = this.height = 0;
|
10313 |
+
return;
|
10314 |
+
}
|
10315 |
+
const labelOpts = options.labels;
|
10316 |
+
const labelFont = toFont(labelOpts.font);
|
10317 |
+
const fontSize = labelFont.size;
|
10318 |
+
const titleHeight = this._computeTitleHeight();
|
10319 |
+
const {boxWidth, itemHeight} = getBoxSize(labelOpts, fontSize);
|
10320 |
+
let width, height;
|
10321 |
+
ctx.font = labelFont.string;
|
10322 |
+
if (this.isHorizontal()) {
|
10323 |
+
width = this.maxWidth;
|
10324 |
+
height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10;
|
10325 |
+
} else {
|
10326 |
+
height = this.maxHeight;
|
10327 |
+
width = this._fitCols(titleHeight, fontSize, boxWidth, itemHeight) + 10;
|
10328 |
+
}
|
10329 |
+
this.width = Math.min(width, options.maxWidth || this.maxWidth);
|
10330 |
+
this.height = Math.min(height, options.maxHeight || this.maxHeight);
|
10331 |
+
}
|
10332 |
+
_fitRows(titleHeight, fontSize, boxWidth, itemHeight) {
|
10333 |
+
const {ctx, maxWidth, options: {labels: {padding}}} = this;
|
10334 |
+
const hitboxes = this.legendHitBoxes = [];
|
10335 |
+
const lineWidths = this.lineWidths = [0];
|
10336 |
+
const lineHeight = itemHeight + padding;
|
10337 |
+
let totalHeight = titleHeight;
|
10338 |
+
ctx.textAlign = 'left';
|
10339 |
+
ctx.textBaseline = 'middle';
|
10340 |
+
let row = -1;
|
10341 |
+
let top = -lineHeight;
|
10342 |
+
this.legendItems.forEach((legendItem, i) => {
|
10343 |
+
const itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
|
10344 |
+
if (i === 0 || lineWidths[lineWidths.length - 1] + itemWidth + 2 * padding > maxWidth) {
|
10345 |
+
totalHeight += lineHeight;
|
10346 |
+
lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0;
|
10347 |
+
top += lineHeight;
|
10348 |
+
row++;
|
10349 |
+
}
|
10350 |
+
hitboxes[i] = {left: 0, top, row, width: itemWidth, height: itemHeight};
|
10351 |
+
lineWidths[lineWidths.length - 1] += itemWidth + padding;
|
10352 |
+
});
|
10353 |
+
return totalHeight;
|
10354 |
+
}
|
10355 |
+
_fitCols(titleHeight, fontSize, boxWidth, itemHeight) {
|
10356 |
+
const {ctx, maxHeight, options: {labels: {padding}}} = this;
|
10357 |
+
const hitboxes = this.legendHitBoxes = [];
|
10358 |
+
const columnSizes = this.columnSizes = [];
|
10359 |
+
const heightLimit = maxHeight - titleHeight;
|
10360 |
+
let totalWidth = padding;
|
10361 |
+
let currentColWidth = 0;
|
10362 |
+
let currentColHeight = 0;
|
10363 |
+
let left = 0;
|
10364 |
+
let col = 0;
|
10365 |
+
this.legendItems.forEach((legendItem, i) => {
|
10366 |
+
const itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
|
10367 |
+
if (i > 0 && currentColHeight + itemHeight + 2 * padding > heightLimit) {
|
10368 |
+
totalWidth += currentColWidth + padding;
|
10369 |
+
columnSizes.push({width: currentColWidth, height: currentColHeight});
|
10370 |
+
left += currentColWidth + padding;
|
10371 |
+
col++;
|
10372 |
+
currentColWidth = currentColHeight = 0;
|
10373 |
+
}
|
10374 |
+
hitboxes[i] = {left, top: currentColHeight, col, width: itemWidth, height: itemHeight};
|
10375 |
+
currentColWidth = Math.max(currentColWidth, itemWidth);
|
10376 |
+
currentColHeight += itemHeight + padding;
|
10377 |
+
});
|
10378 |
+
totalWidth += currentColWidth;
|
10379 |
+
columnSizes.push({width: currentColWidth, height: currentColHeight});
|
10380 |
+
return totalWidth;
|
10381 |
+
}
|
10382 |
+
adjustHitBoxes() {
|
10383 |
+
if (!this.options.display) {
|
10384 |
+
return;
|
10385 |
+
}
|
10386 |
+
const titleHeight = this._computeTitleHeight();
|
10387 |
+
const {legendHitBoxes: hitboxes, options: {align, labels: {padding}, rtl}} = this;
|
10388 |
+
const rtlHelper = getRtlAdapter(rtl, this.left, this.width);
|
10389 |
+
if (this.isHorizontal()) {
|
10390 |
+
let row = 0;
|
10391 |
+
let left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]);
|
10392 |
+
for (const hitbox of hitboxes) {
|
10393 |
+
if (row !== hitbox.row) {
|
10394 |
+
row = hitbox.row;
|
10395 |
+
left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]);
|
10396 |
+
}
|
10397 |
+
hitbox.top += this.top + titleHeight + padding;
|
10398 |
+
hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(left), hitbox.width);
|
10399 |
+
left += hitbox.width + padding;
|
10400 |
+
}
|
10401 |
+
} else {
|
10402 |
+
let col = 0;
|
10403 |
+
let top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height);
|
10404 |
+
for (const hitbox of hitboxes) {
|
10405 |
+
if (hitbox.col !== col) {
|
10406 |
+
col = hitbox.col;
|
10407 |
+
top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height);
|
10408 |
+
}
|
10409 |
+
hitbox.top = top;
|
10410 |
+
hitbox.left += this.left + padding;
|
10411 |
+
hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(hitbox.left), hitbox.width);
|
10412 |
+
top += hitbox.height + padding;
|
10413 |
+
}
|
10414 |
+
}
|
10415 |
+
}
|
10416 |
+
isHorizontal() {
|
10417 |
+
return this.options.position === 'top' || this.options.position === 'bottom';
|
10418 |
+
}
|
10419 |
+
draw() {
|
10420 |
+
if (this.options.display) {
|
10421 |
+
const ctx = this.ctx;
|
10422 |
+
clipArea(ctx, this);
|
10423 |
+
this._draw();
|
10424 |
+
unclipArea(ctx);
|
10425 |
+
}
|
10426 |
+
}
|
10427 |
+
_draw() {
|
10428 |
+
const {options: opts, columnSizes, lineWidths, ctx} = this;
|
10429 |
+
const {align, labels: labelOpts} = opts;
|
10430 |
+
const defaultColor = defaults.color;
|
10431 |
+
const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width);
|
10432 |
+
const labelFont = toFont(labelOpts.font);
|
10433 |
+
const {color: fontColor, padding} = labelOpts;
|
10434 |
+
const fontSize = labelFont.size;
|
10435 |
+
const halfFontSize = fontSize / 2;
|
10436 |
+
let cursor;
|
10437 |
+
this.drawTitle();
|
10438 |
+
ctx.textAlign = rtlHelper.textAlign('left');
|
10439 |
+
ctx.textBaseline = 'middle';
|
10440 |
+
ctx.lineWidth = 0.5;
|
10441 |
+
ctx.font = labelFont.string;
|
10442 |
+
const {boxWidth, boxHeight, itemHeight} = getBoxSize(labelOpts, fontSize);
|
10443 |
+
const drawLegendBox = function(x, y, legendItem) {
|
10444 |
+
if (isNaN(boxWidth) || boxWidth <= 0 || isNaN(boxHeight) || boxHeight < 0) {
|
10445 |
+
return;
|
10446 |
+
}
|
10447 |
+
ctx.save();
|
10448 |
+
const lineWidth = valueOrDefault(legendItem.lineWidth, 1);
|
10449 |
+
ctx.fillStyle = valueOrDefault(legendItem.fillStyle, defaultColor);
|
10450 |
+
ctx.lineCap = valueOrDefault(legendItem.lineCap, 'butt');
|
10451 |
+
ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, 0);
|
10452 |
+
ctx.lineJoin = valueOrDefault(legendItem.lineJoin, 'miter');
|
10453 |
+
ctx.lineWidth = lineWidth;
|
10454 |
+
ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, defaultColor);
|
10455 |
+
ctx.setLineDash(valueOrDefault(legendItem.lineDash, []));
|
10456 |
+
if (labelOpts.usePointStyle) {
|
10457 |
+
const drawOptions = {
|
10458 |
+
radius: boxWidth * Math.SQRT2 / 2,
|
10459 |
+
pointStyle: legendItem.pointStyle,
|
10460 |
+
rotation: legendItem.rotation,
|
10461 |
+
borderWidth: lineWidth
|
10462 |
+
};
|
10463 |
+
const centerX = rtlHelper.xPlus(x, boxWidth / 2);
|
10464 |
+
const centerY = y + halfFontSize;
|
10465 |
+
drawPoint(ctx, drawOptions, centerX, centerY);
|
10466 |
+
} else {
|
10467 |
+
const yBoxTop = y + Math.max((fontSize - boxHeight) / 2, 0);
|
10468 |
+
const xBoxLeft = rtlHelper.leftForLtr(x, boxWidth);
|
10469 |
+
const borderRadius = toTRBLCorners(legendItem.borderRadius);
|
10470 |
+
ctx.beginPath();
|
10471 |
+
if (Object.values(borderRadius).some(v => v !== 0)) {
|
10472 |
+
addRoundedRectPath(ctx, {
|
10473 |
+
x: xBoxLeft,
|
10474 |
+
y: yBoxTop,
|
10475 |
+
w: boxWidth,
|
10476 |
+
h: boxHeight,
|
10477 |
+
radius: borderRadius,
|
10478 |
+
});
|
10479 |
+
} else {
|
10480 |
+
ctx.rect(xBoxLeft, yBoxTop, boxWidth, boxHeight);
|
10481 |
+
}
|
10482 |
+
ctx.fill();
|
10483 |
+
if (lineWidth !== 0) {
|
10484 |
+
ctx.stroke();
|
10485 |
+
}
|
10486 |
+
}
|
10487 |
+
ctx.restore();
|
10488 |
+
};
|
10489 |
+
const fillText = function(x, y, legendItem) {
|
10490 |
+
renderText(ctx, legendItem.text, x, y + (itemHeight / 2), labelFont, {
|
10491 |
+
strikethrough: legendItem.hidden,
|
10492 |
+
textAlign: rtlHelper.textAlign(legendItem.textAlign)
|
10493 |
+
});
|
10494 |
+
};
|
10495 |
+
const isHorizontal = this.isHorizontal();
|
10496 |
+
const titleHeight = this._computeTitleHeight();
|
10497 |
+
if (isHorizontal) {
|
10498 |
+
cursor = {
|
10499 |
+
x: _alignStartEnd(align, this.left + padding, this.right - lineWidths[0]),
|
10500 |
+
y: this.top + padding + titleHeight,
|
10501 |
+
line: 0
|
10502 |
+
};
|
10503 |
+
} else {
|
10504 |
+
cursor = {
|
10505 |
+
x: this.left + padding,
|
10506 |
+
y: _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[0].height),
|
10507 |
+
line: 0
|
10508 |
+
};
|
10509 |
+
}
|
10510 |
+
overrideTextDirection(this.ctx, opts.textDirection);
|
10511 |
+
const lineHeight = itemHeight + padding;
|
10512 |
+
this.legendItems.forEach((legendItem, i) => {
|
10513 |
+
ctx.strokeStyle = legendItem.fontColor || fontColor;
|
10514 |
+
ctx.fillStyle = legendItem.fontColor || fontColor;
|
10515 |
+
const textWidth = ctx.measureText(legendItem.text).width;
|
10516 |
+
const textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign));
|
10517 |
+
const width = boxWidth + halfFontSize + textWidth;
|
10518 |
+
let x = cursor.x;
|
10519 |
+
let y = cursor.y;
|
10520 |
+
rtlHelper.setWidth(this.width);
|
10521 |
+
if (isHorizontal) {
|
10522 |
+
if (i > 0 && x + width + padding > this.right) {
|
10523 |
+
y = cursor.y += lineHeight;
|
10524 |
+
cursor.line++;
|
10525 |
+
x = cursor.x = _alignStartEnd(align, this.left + padding, this.right - lineWidths[cursor.line]);
|
10526 |
+
}
|
10527 |
+
} else if (i > 0 && y + lineHeight > this.bottom) {
|
10528 |
+
x = cursor.x = x + columnSizes[cursor.line].width + padding;
|
10529 |
+
cursor.line++;
|
10530 |
+
y = cursor.y = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[cursor.line].height);
|
10531 |
+
}
|
10532 |
+
const realX = rtlHelper.x(x);
|
10533 |
+
drawLegendBox(realX, y, legendItem);
|
10534 |
+
x = _textX(textAlign, x + boxWidth + halfFontSize, isHorizontal ? x + width : this.right, opts.rtl);
|
10535 |
+
fillText(rtlHelper.x(x), y, legendItem);
|
10536 |
+
if (isHorizontal) {
|
10537 |
+
cursor.x += width + padding;
|
10538 |
+
} else {
|
10539 |
+
cursor.y += lineHeight;
|
10540 |
+
}
|
10541 |
+
});
|
10542 |
+
restoreTextDirection(this.ctx, opts.textDirection);
|
10543 |
+
}
|
10544 |
+
drawTitle() {
|
10545 |
+
const opts = this.options;
|
10546 |
+
const titleOpts = opts.title;
|
10547 |
+
const titleFont = toFont(titleOpts.font);
|
10548 |
+
const titlePadding = toPadding(titleOpts.padding);
|
10549 |
+
if (!titleOpts.display) {
|
10550 |
+
return;
|
10551 |
+
}
|
10552 |
+
const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width);
|
10553 |
+
const ctx = this.ctx;
|
10554 |
+
const position = titleOpts.position;
|
10555 |
+
const halfFontSize = titleFont.size / 2;
|
10556 |
+
const topPaddingPlusHalfFontSize = titlePadding.top + halfFontSize;
|
10557 |
+
let y;
|
10558 |
+
let left = this.left;
|
10559 |
+
let maxWidth = this.width;
|
10560 |
+
if (this.isHorizontal()) {
|
10561 |
+
maxWidth = Math.max(...this.lineWidths);
|
10562 |
+
y = this.top + topPaddingPlusHalfFontSize;
|
10563 |
+
left = _alignStartEnd(opts.align, left, this.right - maxWidth);
|
10564 |
+
} else {
|
10565 |
+
const maxHeight = this.columnSizes.reduce((acc, size) => Math.max(acc, size.height), 0);
|
10566 |
+
y = topPaddingPlusHalfFontSize + _alignStartEnd(opts.align, this.top, this.bottom - maxHeight - opts.labels.padding - this._computeTitleHeight());
|
10567 |
+
}
|
10568 |
+
const x = _alignStartEnd(position, left, left + maxWidth);
|
10569 |
+
ctx.textAlign = rtlHelper.textAlign(_toLeftRightCenter(position));
|
10570 |
+
ctx.textBaseline = 'middle';
|
10571 |
+
ctx.strokeStyle = titleOpts.color;
|
10572 |
+
ctx.fillStyle = titleOpts.color;
|
10573 |
+
ctx.font = titleFont.string;
|
10574 |
+
renderText(ctx, titleOpts.text, x, y, titleFont);
|
10575 |
+
}
|
10576 |
+
_computeTitleHeight() {
|
10577 |
+
const titleOpts = this.options.title;
|
10578 |
+
const titleFont = toFont(titleOpts.font);
|
10579 |
+
const titlePadding = toPadding(titleOpts.padding);
|
10580 |
+
return titleOpts.display ? titleFont.lineHeight + titlePadding.height : 0;
|
10581 |
+
}
|
10582 |
+
_getLegendItemAt(x, y) {
|
10583 |
+
let i, hitBox, lh;
|
10584 |
+
if (_isBetween(x, this.left, this.right)
|
10585 |
+
&& _isBetween(y, this.top, this.bottom)) {
|
10586 |
+
lh = this.legendHitBoxes;
|
10587 |
+
for (i = 0; i < lh.length; ++i) {
|
10588 |
+
hitBox = lh[i];
|
10589 |
+
if (_isBetween(x, hitBox.left, hitBox.left + hitBox.width)
|
10590 |
+
&& _isBetween(y, hitBox.top, hitBox.top + hitBox.height)) {
|
10591 |
+
return this.legendItems[i];
|
10592 |
+
}
|
10593 |
+
}
|
10594 |
+
}
|
10595 |
+
return null;
|
10596 |
+
}
|
10597 |
+
handleEvent(e) {
|
10598 |
+
const opts = this.options;
|
10599 |
+
if (!isListened(e.type, opts)) {
|
10600 |
+
return;
|
10601 |
+
}
|
10602 |
+
const hoveredItem = this._getLegendItemAt(e.x, e.y);
|
10603 |
+
if (e.type === 'mousemove') {
|
10604 |
+
const previous = this._hoveredItem;
|
10605 |
+
const sameItem = itemsEqual(previous, hoveredItem);
|
10606 |
+
if (previous && !sameItem) {
|
10607 |
+
callback(opts.onLeave, [e, previous, this], this);
|
10608 |
+
}
|
10609 |
+
this._hoveredItem = hoveredItem;
|
10610 |
+
if (hoveredItem && !sameItem) {
|
10611 |
+
callback(opts.onHover, [e, hoveredItem, this], this);
|
10612 |
+
}
|
10613 |
+
} else if (hoveredItem) {
|
10614 |
+
callback(opts.onClick, [e, hoveredItem, this], this);
|
10615 |
+
}
|
10616 |
+
}
|
10617 |
+
}
|
10618 |
+
function isListened(type, opts) {
|
10619 |
+
if (type === 'mousemove' && (opts.onHover || opts.onLeave)) {
|
10620 |
+
return true;
|
10621 |
+
}
|
10622 |
+
if (opts.onClick && (type === 'click' || type === 'mouseup')) {
|
10623 |
+
return true;
|
10624 |
+
}
|
10625 |
+
return false;
|
10626 |
+
}
|
10627 |
+
var plugin_legend = {
|
10628 |
+
id: 'legend',
|
10629 |
+
_element: Legend,
|
10630 |
+
start(chart, _args, options) {
|
10631 |
+
const legend = chart.legend = new Legend({ctx: chart.ctx, options, chart});
|
10632 |
+
layouts.configure(chart, legend, options);
|
10633 |
+
layouts.addBox(chart, legend);
|
10634 |
+
},
|
10635 |
+
stop(chart) {
|
10636 |
+
layouts.removeBox(chart, chart.legend);
|
10637 |
+
delete chart.legend;
|
10638 |
+
},
|
10639 |
+
beforeUpdate(chart, _args, options) {
|
10640 |
+
const legend = chart.legend;
|
10641 |
+
layouts.configure(chart, legend, options);
|
10642 |
+
legend.options = options;
|
10643 |
+
},
|
10644 |
+
afterUpdate(chart) {
|
10645 |
+
const legend = chart.legend;
|
10646 |
+
legend.buildLabels();
|
10647 |
+
legend.adjustHitBoxes();
|
10648 |
+
},
|
10649 |
+
afterEvent(chart, args) {
|
10650 |
+
if (!args.replay) {
|
10651 |
+
chart.legend.handleEvent(args.event);
|
10652 |
+
}
|
10653 |
+
},
|
10654 |
+
defaults: {
|
10655 |
+
display: true,
|
10656 |
+
position: 'top',
|
10657 |
+
align: 'center',
|
10658 |
+
fullSize: true,
|
10659 |
+
reverse: false,
|
10660 |
+
weight: 1000,
|
10661 |
+
onClick(e, legendItem, legend) {
|
10662 |
+
const index = legendItem.datasetIndex;
|
10663 |
+
const ci = legend.chart;
|
10664 |
+
if (ci.isDatasetVisible(index)) {
|
10665 |
+
ci.hide(index);
|
10666 |
+
legendItem.hidden = true;
|
10667 |
+
} else {
|
10668 |
+
ci.show(index);
|
10669 |
+
legendItem.hidden = false;
|
10670 |
+
}
|
10671 |
+
},
|
10672 |
+
onHover: null,
|
10673 |
+
onLeave: null,
|
10674 |
+
labels: {
|
10675 |
+
color: (ctx) => ctx.chart.options.color,
|
10676 |
+
boxWidth: 40,
|
10677 |
+
padding: 10,
|
10678 |
+
generateLabels(chart) {
|
10679 |
+
const datasets = chart.data.datasets;
|
10680 |
+
const {labels: {usePointStyle, pointStyle, textAlign, color}} = chart.legend.options;
|
10681 |
+
return chart._getSortedDatasetMetas().map((meta) => {
|
10682 |
+
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
|
10683 |
+
const borderWidth = toPadding(style.borderWidth);
|
10684 |
+
return {
|
10685 |
+
text: datasets[meta.index].label,
|
10686 |
+
fillStyle: style.backgroundColor,
|
10687 |
+
fontColor: color,
|
10688 |
+
hidden: !meta.visible,
|
10689 |
+
lineCap: style.borderCapStyle,
|
10690 |
+
lineDash: style.borderDash,
|
10691 |
+
lineDashOffset: style.borderDashOffset,
|
10692 |
+
lineJoin: style.borderJoinStyle,
|
10693 |
+
lineWidth: (borderWidth.width + borderWidth.height) / 4,
|
10694 |
+
strokeStyle: style.borderColor,
|
10695 |
+
pointStyle: pointStyle || style.pointStyle,
|
10696 |
+
rotation: style.rotation,
|
10697 |
+
textAlign: textAlign || style.textAlign,
|
10698 |
+
borderRadius: 0,
|
10699 |
+
datasetIndex: meta.index
|
10700 |
+
};
|
10701 |
+
}, this);
|
10702 |
+
}
|
10703 |
+
},
|
10704 |
+
title: {
|
10705 |
+
color: (ctx) => ctx.chart.options.color,
|
10706 |
+
display: false,
|
10707 |
+
position: 'center',
|
10708 |
+
text: '',
|
10709 |
+
}
|
10710 |
+
},
|
10711 |
+
descriptors: {
|
10712 |
+
_scriptable: (name) => !name.startsWith('on'),
|
10713 |
+
labels: {
|
10714 |
+
_scriptable: (name) => !['generateLabels', 'filter', 'sort'].includes(name),
|
10715 |
+
}
|
10716 |
+
},
|
10717 |
+
};
|
10718 |
+
|
10719 |
+
class Title extends Element {
|
10720 |
+
constructor(config) {
|
10721 |
+
super();
|
10722 |
+
this.chart = config.chart;
|
10723 |
+
this.options = config.options;
|
10724 |
+
this.ctx = config.ctx;
|
10725 |
+
this._padding = undefined;
|
10726 |
+
this.top = undefined;
|
10727 |
+
this.bottom = undefined;
|
10728 |
+
this.left = undefined;
|
10729 |
+
this.right = undefined;
|
10730 |
+
this.width = undefined;
|
10731 |
+
this.height = undefined;
|
10732 |
+
this.position = undefined;
|
10733 |
+
this.weight = undefined;
|
10734 |
+
this.fullSize = undefined;
|
10735 |
+
}
|
10736 |
+
update(maxWidth, maxHeight) {
|
10737 |
+
const opts = this.options;
|
10738 |
+
this.left = 0;
|
10739 |
+
this.top = 0;
|
10740 |
+
if (!opts.display) {
|
10741 |
+
this.width = this.height = this.right = this.bottom = 0;
|
10742 |
+
return;
|
10743 |
+
}
|
10744 |
+
this.width = this.right = maxWidth;
|
10745 |
+
this.height = this.bottom = maxHeight;
|
10746 |
+
const lineCount = isArray(opts.text) ? opts.text.length : 1;
|
10747 |
+
this._padding = toPadding(opts.padding);
|
10748 |
+
const textSize = lineCount * toFont(opts.font).lineHeight + this._padding.height;
|
10749 |
+
if (this.isHorizontal()) {
|
10750 |
+
this.height = textSize;
|
10751 |
+
} else {
|
10752 |
+
this.width = textSize;
|
10753 |
+
}
|
10754 |
+
}
|
10755 |
+
isHorizontal() {
|
10756 |
+
const pos = this.options.position;
|
10757 |
+
return pos === 'top' || pos === 'bottom';
|
10758 |
+
}
|
10759 |
+
_drawArgs(offset) {
|
10760 |
+
const {top, left, bottom, right, options} = this;
|
10761 |
+
const align = options.align;
|
10762 |
+
let rotation = 0;
|
10763 |
+
let maxWidth, titleX, titleY;
|
10764 |
+
if (this.isHorizontal()) {
|
10765 |
+
titleX = _alignStartEnd(align, left, right);
|
10766 |
+
titleY = top + offset;
|
10767 |
+
maxWidth = right - left;
|
10768 |
+
} else {
|
10769 |
+
if (options.position === 'left') {
|
10770 |
+
titleX = left + offset;
|
10771 |
+
titleY = _alignStartEnd(align, bottom, top);
|
10772 |
+
rotation = PI * -0.5;
|
10773 |
+
} else {
|
10774 |
+
titleX = right - offset;
|
10775 |
+
titleY = _alignStartEnd(align, top, bottom);
|
10776 |
+
rotation = PI * 0.5;
|
10777 |
+
}
|
10778 |
+
maxWidth = bottom - top;
|
10779 |
+
}
|
10780 |
+
return {titleX, titleY, maxWidth, rotation};
|
10781 |
+
}
|
10782 |
+
draw() {
|
10783 |
+
const ctx = this.ctx;
|
10784 |
+
const opts = this.options;
|
10785 |
+
if (!opts.display) {
|
10786 |
+
return;
|
10787 |
+
}
|
10788 |
+
const fontOpts = toFont(opts.font);
|
10789 |
+
const lineHeight = fontOpts.lineHeight;
|
10790 |
+
const offset = lineHeight / 2 + this._padding.top;
|
10791 |
+
const {titleX, titleY, maxWidth, rotation} = this._drawArgs(offset);
|
10792 |
+
renderText(ctx, opts.text, 0, 0, fontOpts, {
|
10793 |
+
color: opts.color,
|
10794 |
+
maxWidth,
|
10795 |
+
rotation,
|
10796 |
+
textAlign: _toLeftRightCenter(opts.align),
|
10797 |
+
textBaseline: 'middle',
|
10798 |
+
translation: [titleX, titleY],
|
10799 |
+
});
|
10800 |
+
}
|
10801 |
+
}
|
10802 |
+
function createTitle(chart, titleOpts) {
|
10803 |
+
const title = new Title({
|
10804 |
+
ctx: chart.ctx,
|
10805 |
+
options: titleOpts,
|
10806 |
+
chart
|
10807 |
+
});
|
10808 |
+
layouts.configure(chart, title, titleOpts);
|
10809 |
+
layouts.addBox(chart, title);
|
10810 |
+
chart.titleBlock = title;
|
10811 |
+
}
|
10812 |
+
var plugin_title = {
|
10813 |
+
id: 'title',
|
10814 |
+
_element: Title,
|
10815 |
+
start(chart, _args, options) {
|
10816 |
+
createTitle(chart, options);
|
10817 |
+
},
|
10818 |
+
stop(chart) {
|
10819 |
+
const titleBlock = chart.titleBlock;
|
10820 |
+
layouts.removeBox(chart, titleBlock);
|
10821 |
+
delete chart.titleBlock;
|
10822 |
+
},
|
10823 |
+
beforeUpdate(chart, _args, options) {
|
10824 |
+
const title = chart.titleBlock;
|
10825 |
+
layouts.configure(chart, title, options);
|
10826 |
+
title.options = options;
|
10827 |
+
},
|
10828 |
+
defaults: {
|
10829 |
+
align: 'center',
|
10830 |
+
display: false,
|
10831 |
+
font: {
|
10832 |
+
weight: 'bold',
|
10833 |
+
},
|
10834 |
+
fullSize: true,
|
10835 |
+
padding: 10,
|
10836 |
+
position: 'top',
|
10837 |
+
text: '',
|
10838 |
+
weight: 2000
|
10839 |
+
},
|
10840 |
+
defaultRoutes: {
|
10841 |
+
color: 'color'
|
10842 |
+
},
|
10843 |
+
descriptors: {
|
10844 |
+
_scriptable: true,
|
10845 |
+
_indexable: false,
|
10846 |
+
},
|
10847 |
+
};
|
10848 |
+
|
10849 |
+
const map = new WeakMap();
|
10850 |
+
var plugin_subtitle = {
|
10851 |
+
id: 'subtitle',
|
10852 |
+
start(chart, _args, options) {
|
10853 |
+
const title = new Title({
|
10854 |
+
ctx: chart.ctx,
|
10855 |
+
options,
|
10856 |
+
chart
|
10857 |
+
});
|
10858 |
+
layouts.configure(chart, title, options);
|
10859 |
+
layouts.addBox(chart, title);
|
10860 |
+
map.set(chart, title);
|
10861 |
+
},
|
10862 |
+
stop(chart) {
|
10863 |
+
layouts.removeBox(chart, map.get(chart));
|
10864 |
+
map.delete(chart);
|
10865 |
+
},
|
10866 |
+
beforeUpdate(chart, _args, options) {
|
10867 |
+
const title = map.get(chart);
|
10868 |
+
layouts.configure(chart, title, options);
|
10869 |
+
title.options = options;
|
10870 |
+
},
|
10871 |
+
defaults: {
|
10872 |
+
align: 'center',
|
10873 |
+
display: false,
|
10874 |
+
font: {
|
10875 |
+
weight: 'normal',
|
10876 |
+
},
|
10877 |
+
fullSize: true,
|
10878 |
+
padding: 0,
|
10879 |
+
position: 'top',
|
10880 |
+
text: '',
|
10881 |
+
weight: 1500
|
10882 |
+
},
|
10883 |
+
defaultRoutes: {
|
10884 |
+
color: 'color'
|
10885 |
+
},
|
10886 |
+
descriptors: {
|
10887 |
+
_scriptable: true,
|
10888 |
+
_indexable: false,
|
10889 |
+
},
|
10890 |
+
};
|
10891 |
+
|
10892 |
+
const positioners = {
|
10893 |
+
average(items) {
|
10894 |
+
if (!items.length) {
|
10895 |
+
return false;
|
10896 |
+
}
|
10897 |
+
let i, len;
|
10898 |
+
let x = 0;
|
10899 |
+
let y = 0;
|
10900 |
+
let count = 0;
|
10901 |
+
for (i = 0, len = items.length; i < len; ++i) {
|
10902 |
+
const el = items[i].element;
|
10903 |
+
if (el && el.hasValue()) {
|
10904 |
+
const pos = el.tooltipPosition();
|
10905 |
+
x += pos.x;
|
10906 |
+
y += pos.y;
|
10907 |
+
++count;
|
10908 |
+
}
|
10909 |
+
}
|
10910 |
+
return {
|
10911 |
+
x: x / count,
|
10912 |
+
y: y / count
|
10913 |
+
};
|
10914 |
+
},
|
10915 |
+
nearest(items, eventPosition) {
|
10916 |
+
if (!items.length) {
|
10917 |
+
return false;
|
10918 |
+
}
|
10919 |
+
let x = eventPosition.x;
|
10920 |
+
let y = eventPosition.y;
|
10921 |
+
let minDistance = Number.POSITIVE_INFINITY;
|
10922 |
+
let i, len, nearestElement;
|
10923 |
+
for (i = 0, len = items.length; i < len; ++i) {
|
10924 |
+
const el = items[i].element;
|
10925 |
+
if (el && el.hasValue()) {
|
10926 |
+
const center = el.getCenterPoint();
|
10927 |
+
const d = distanceBetweenPoints(eventPosition, center);
|
10928 |
+
if (d < minDistance) {
|
10929 |
+
minDistance = d;
|
10930 |
+
nearestElement = el;
|
10931 |
+
}
|
10932 |
+
}
|
10933 |
+
}
|
10934 |
+
if (nearestElement) {
|
10935 |
+
const tp = nearestElement.tooltipPosition();
|
10936 |
+
x = tp.x;
|
10937 |
+
y = tp.y;
|
10938 |
+
}
|
10939 |
+
return {
|
10940 |
+
x,
|
10941 |
+
y
|
10942 |
+
};
|
10943 |
+
}
|
10944 |
+
};
|
10945 |
+
function pushOrConcat(base, toPush) {
|
10946 |
+
if (toPush) {
|
10947 |
+
if (isArray(toPush)) {
|
10948 |
+
Array.prototype.push.apply(base, toPush);
|
10949 |
+
} else {
|
10950 |
+
base.push(toPush);
|
10951 |
+
}
|
10952 |
+
}
|
10953 |
+
return base;
|
10954 |
+
}
|
10955 |
+
function splitNewlines(str) {
|
10956 |
+
if ((typeof str === 'string' || str instanceof String) && str.indexOf('\n') > -1) {
|
10957 |
+
return str.split('\n');
|
10958 |
+
}
|
10959 |
+
return str;
|
10960 |
+
}
|
10961 |
+
function createTooltipItem(chart, item) {
|
10962 |
+
const {element, datasetIndex, index} = item;
|
10963 |
+
const controller = chart.getDatasetMeta(datasetIndex).controller;
|
10964 |
+
const {label, value} = controller.getLabelAndValue(index);
|
10965 |
+
return {
|
10966 |
+
chart,
|
10967 |
+
label,
|
10968 |
+
parsed: controller.getParsed(index),
|
10969 |
+
raw: chart.data.datasets[datasetIndex].data[index],
|
10970 |
+
formattedValue: value,
|
10971 |
+
dataset: controller.getDataset(),
|
10972 |
+
dataIndex: index,
|
10973 |
+
datasetIndex,
|
10974 |
+
element
|
10975 |
+
};
|
10976 |
+
}
|
10977 |
+
function getTooltipSize(tooltip, options) {
|
10978 |
+
const ctx = tooltip.chart.ctx;
|
10979 |
+
const {body, footer, title} = tooltip;
|
10980 |
+
const {boxWidth, boxHeight} = options;
|
10981 |
+
const bodyFont = toFont(options.bodyFont);
|
10982 |
+
const titleFont = toFont(options.titleFont);
|
10983 |
+
const footerFont = toFont(options.footerFont);
|
10984 |
+
const titleLineCount = title.length;
|
10985 |
+
const footerLineCount = footer.length;
|
10986 |
+
const bodyLineItemCount = body.length;
|
10987 |
+
const padding = toPadding(options.padding);
|
10988 |
+
let height = padding.height;
|
10989 |
+
let width = 0;
|
10990 |
+
let combinedBodyLength = body.reduce((count, bodyItem) => count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length, 0);
|
10991 |
+
combinedBodyLength += tooltip.beforeBody.length + tooltip.afterBody.length;
|
10992 |
+
if (titleLineCount) {
|
10993 |
+
height += titleLineCount * titleFont.lineHeight
|
10994 |
+
+ (titleLineCount - 1) * options.titleSpacing
|
10995 |
+
+ options.titleMarginBottom;
|
10996 |
+
}
|
10997 |
+
if (combinedBodyLength) {
|
10998 |
+
const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFont.lineHeight) : bodyFont.lineHeight;
|
10999 |
+
height += bodyLineItemCount * bodyLineHeight
|
11000 |
+
+ (combinedBodyLength - bodyLineItemCount) * bodyFont.lineHeight
|
11001 |
+
+ (combinedBodyLength - 1) * options.bodySpacing;
|
11002 |
+
}
|
11003 |
+
if (footerLineCount) {
|
11004 |
+
height += options.footerMarginTop
|
11005 |
+
+ footerLineCount * footerFont.lineHeight
|
11006 |
+
+ (footerLineCount - 1) * options.footerSpacing;
|
11007 |
+
}
|
11008 |
+
let widthPadding = 0;
|
11009 |
+
const maxLineWidth = function(line) {
|
11010 |
+
width = Math.max(width, ctx.measureText(line).width + widthPadding);
|
11011 |
+
};
|
11012 |
+
ctx.save();
|
11013 |
+
ctx.font = titleFont.string;
|
11014 |
+
each(tooltip.title, maxLineWidth);
|
11015 |
+
ctx.font = bodyFont.string;
|
11016 |
+
each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth);
|
11017 |
+
widthPadding = options.displayColors ? (boxWidth + 2 + options.boxPadding) : 0;
|
11018 |
+
each(body, (bodyItem) => {
|
11019 |
+
each(bodyItem.before, maxLineWidth);
|
11020 |
+
each(bodyItem.lines, maxLineWidth);
|
11021 |
+
each(bodyItem.after, maxLineWidth);
|
11022 |
+
});
|
11023 |
+
widthPadding = 0;
|
11024 |
+
ctx.font = footerFont.string;
|
11025 |
+
each(tooltip.footer, maxLineWidth);
|
11026 |
+
ctx.restore();
|
11027 |
+
width += padding.width;
|
11028 |
+
return {width, height};
|
11029 |
+
}
|
11030 |
+
function determineYAlign(chart, size) {
|
11031 |
+
const {y, height} = size;
|
11032 |
+
if (y < height / 2) {
|
11033 |
+
return 'top';
|
11034 |
+
} else if (y > (chart.height - height / 2)) {
|
11035 |
+
return 'bottom';
|
11036 |
+
}
|
11037 |
+
return 'center';
|
11038 |
+
}
|
11039 |
+
function doesNotFitWithAlign(xAlign, chart, options, size) {
|
11040 |
+
const {x, width} = size;
|
11041 |
+
const caret = options.caretSize + options.caretPadding;
|
11042 |
+
if (xAlign === 'left' && x + width + caret > chart.width) {
|
11043 |
+
return true;
|
11044 |
+
}
|
11045 |
+
if (xAlign === 'right' && x - width - caret < 0) {
|
11046 |
+
return true;
|
11047 |
+
}
|
11048 |
+
}
|
11049 |
+
function determineXAlign(chart, options, size, yAlign) {
|
11050 |
+
const {x, width} = size;
|
11051 |
+
const {width: chartWidth, chartArea: {left, right}} = chart;
|
11052 |
+
let xAlign = 'center';
|
11053 |
+
if (yAlign === 'center') {
|
11054 |
+
xAlign = x <= (left + right) / 2 ? 'left' : 'right';
|
11055 |
+
} else if (x <= width / 2) {
|
11056 |
+
xAlign = 'left';
|
11057 |
+
} else if (x >= chartWidth - width / 2) {
|
11058 |
+
xAlign = 'right';
|
11059 |
+
}
|
11060 |
+
if (doesNotFitWithAlign(xAlign, chart, options, size)) {
|
11061 |
+
xAlign = 'center';
|
11062 |
+
}
|
11063 |
+
return xAlign;
|
11064 |
+
}
|
11065 |
+
function determineAlignment(chart, options, size) {
|
11066 |
+
const yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size);
|
11067 |
+
return {
|
11068 |
+
xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign),
|
11069 |
+
yAlign
|
11070 |
+
};
|
11071 |
+
}
|
11072 |
+
function alignX(size, xAlign) {
|
11073 |
+
let {x, width} = size;
|
11074 |
+
if (xAlign === 'right') {
|
11075 |
+
x -= width;
|
11076 |
+
} else if (xAlign === 'center') {
|
11077 |
+
x -= (width / 2);
|
11078 |
+
}
|
11079 |
+
return x;
|
11080 |
+
}
|
11081 |
+
function alignY(size, yAlign, paddingAndSize) {
|
11082 |
+
let {y, height} = size;
|
11083 |
+
if (yAlign === 'top') {
|
11084 |
+
y += paddingAndSize;
|
11085 |
+
} else if (yAlign === 'bottom') {
|
11086 |
+
y -= height + paddingAndSize;
|
11087 |
+
} else {
|
11088 |
+
y -= (height / 2);
|
11089 |
+
}
|
11090 |
+
return y;
|
11091 |
+
}
|
11092 |
+
function getBackgroundPoint(options, size, alignment, chart) {
|
11093 |
+
const {caretSize, caretPadding, cornerRadius} = options;
|
11094 |
+
const {xAlign, yAlign} = alignment;
|
11095 |
+
const paddingAndSize = caretSize + caretPadding;
|
11096 |
+
const {topLeft, topRight, bottomLeft, bottomRight} = toTRBLCorners(cornerRadius);
|
11097 |
+
let x = alignX(size, xAlign);
|
11098 |
+
const y = alignY(size, yAlign, paddingAndSize);
|
11099 |
+
if (yAlign === 'center') {
|
11100 |
+
if (xAlign === 'left') {
|
11101 |
+
x += paddingAndSize;
|
11102 |
+
} else if (xAlign === 'right') {
|
11103 |
+
x -= paddingAndSize;
|
11104 |
+
}
|
11105 |
+
} else if (xAlign === 'left') {
|
11106 |
+
x -= Math.max(topLeft, bottomLeft) + caretSize;
|
11107 |
+
} else if (xAlign === 'right') {
|
11108 |
+
x += Math.max(topRight, bottomRight) + caretSize;
|
11109 |
+
}
|
11110 |
+
return {
|
11111 |
+
x: _limitValue(x, 0, chart.width - size.width),
|
11112 |
+
y: _limitValue(y, 0, chart.height - size.height)
|
11113 |
+
};
|
11114 |
+
}
|
11115 |
+
function getAlignedX(tooltip, align, options) {
|
11116 |
+
const padding = toPadding(options.padding);
|
11117 |
+
return align === 'center'
|
11118 |
+
? tooltip.x + tooltip.width / 2
|
11119 |
+
: align === 'right'
|
11120 |
+
? tooltip.x + tooltip.width - padding.right
|
11121 |
+
: tooltip.x + padding.left;
|
11122 |
+
}
|
11123 |
+
function getBeforeAfterBodyLines(callback) {
|
11124 |
+
return pushOrConcat([], splitNewlines(callback));
|
11125 |
+
}
|
11126 |
+
function createTooltipContext(parent, tooltip, tooltipItems) {
|
11127 |
+
return createContext(parent, {
|
11128 |
+
tooltip,
|
11129 |
+
tooltipItems,
|
11130 |
+
type: 'tooltip'
|
11131 |
+
});
|
11132 |
+
}
|
11133 |
+
function overrideCallbacks(callbacks, context) {
|
11134 |
+
const override = context && context.dataset && context.dataset.tooltip && context.dataset.tooltip.callbacks;
|
11135 |
+
return override ? callbacks.override(override) : callbacks;
|
11136 |
+
}
|
11137 |
+
class Tooltip extends Element {
|
11138 |
+
constructor(config) {
|
11139 |
+
super();
|
11140 |
+
this.opacity = 0;
|
11141 |
+
this._active = [];
|
11142 |
+
this._eventPosition = undefined;
|
11143 |
+
this._size = undefined;
|
11144 |
+
this._cachedAnimations = undefined;
|
11145 |
+
this._tooltipItems = [];
|
11146 |
+
this.$animations = undefined;
|
11147 |
+
this.$context = undefined;
|
11148 |
+
this.chart = config.chart || config._chart;
|
11149 |
+
this._chart = this.chart;
|
11150 |
+
this.options = config.options;
|
11151 |
+
this.dataPoints = undefined;
|
11152 |
+
this.title = undefined;
|
11153 |
+
this.beforeBody = undefined;
|
11154 |
+
this.body = undefined;
|
11155 |
+
this.afterBody = undefined;
|
11156 |
+
this.footer = undefined;
|
11157 |
+
this.xAlign = undefined;
|
11158 |
+
this.yAlign = undefined;
|
11159 |
+
this.x = undefined;
|
11160 |
+
this.y = undefined;
|
11161 |
+
this.height = undefined;
|
11162 |
+
this.width = undefined;
|
11163 |
+
this.caretX = undefined;
|
11164 |
+
this.caretY = undefined;
|
11165 |
+
this.labelColors = undefined;
|
11166 |
+
this.labelPointStyles = undefined;
|
11167 |
+
this.labelTextColors = undefined;
|
11168 |
+
}
|
11169 |
+
initialize(options) {
|
11170 |
+
this.options = options;
|
11171 |
+
this._cachedAnimations = undefined;
|
11172 |
+
this.$context = undefined;
|
11173 |
+
}
|
11174 |
+
_resolveAnimations() {
|
11175 |
+
const cached = this._cachedAnimations;
|
11176 |
+
if (cached) {
|
11177 |
+
return cached;
|
11178 |
+
}
|
11179 |
+
const chart = this.chart;
|
11180 |
+
const options = this.options.setContext(this.getContext());
|
11181 |
+
const opts = options.enabled && chart.options.animation && options.animations;
|
11182 |
+
const animations = new Animations(this.chart, opts);
|
11183 |
+
if (opts._cacheable) {
|
11184 |
+
this._cachedAnimations = Object.freeze(animations);
|
11185 |
+
}
|
11186 |
+
return animations;
|
11187 |
+
}
|
11188 |
+
getContext() {
|
11189 |
+
return this.$context ||
|
11190 |
+
(this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems));
|
11191 |
+
}
|
11192 |
+
getTitle(context, options) {
|
11193 |
+
const {callbacks} = options;
|
11194 |
+
const beforeTitle = callbacks.beforeTitle.apply(this, [context]);
|
11195 |
+
const title = callbacks.title.apply(this, [context]);
|
11196 |
+
const afterTitle = callbacks.afterTitle.apply(this, [context]);
|
11197 |
+
let lines = [];
|
11198 |
+
lines = pushOrConcat(lines, splitNewlines(beforeTitle));
|
11199 |
+
lines = pushOrConcat(lines, splitNewlines(title));
|
11200 |
+
lines = pushOrConcat(lines, splitNewlines(afterTitle));
|
11201 |
+
return lines;
|
11202 |
+
}
|
11203 |
+
getBeforeBody(tooltipItems, options) {
|
11204 |
+
return getBeforeAfterBodyLines(options.callbacks.beforeBody.apply(this, [tooltipItems]));
|
11205 |
+
}
|
11206 |
+
getBody(tooltipItems, options) {
|
11207 |
+
const {callbacks} = options;
|
11208 |
+
const bodyItems = [];
|
11209 |
+
each(tooltipItems, (context) => {
|
11210 |
+
const bodyItem = {
|
11211 |
+
before: [],
|
11212 |
+
lines: [],
|
11213 |
+
after: []
|
11214 |
+
};
|
11215 |
+
const scoped = overrideCallbacks(callbacks, context);
|
11216 |
+
pushOrConcat(bodyItem.before, splitNewlines(scoped.beforeLabel.call(this, context)));
|
11217 |
+
pushOrConcat(bodyItem.lines, scoped.label.call(this, context));
|
11218 |
+
pushOrConcat(bodyItem.after, splitNewlines(scoped.afterLabel.call(this, context)));
|
11219 |
+
bodyItems.push(bodyItem);
|
11220 |
+
});
|
11221 |
+
return bodyItems;
|
11222 |
+
}
|
11223 |
+
getAfterBody(tooltipItems, options) {
|
11224 |
+
return getBeforeAfterBodyLines(options.callbacks.afterBody.apply(this, [tooltipItems]));
|
11225 |
+
}
|
11226 |
+
getFooter(tooltipItems, options) {
|
11227 |
+
const {callbacks} = options;
|
11228 |
+
const beforeFooter = callbacks.beforeFooter.apply(this, [tooltipItems]);
|
11229 |
+
const footer = callbacks.footer.apply(this, [tooltipItems]);
|
11230 |
+
const afterFooter = callbacks.afterFooter.apply(this, [tooltipItems]);
|
11231 |
+
let lines = [];
|
11232 |
+
lines = pushOrConcat(lines, splitNewlines(beforeFooter));
|
11233 |
+
lines = pushOrConcat(lines, splitNewlines(footer));
|
11234 |
+
lines = pushOrConcat(lines, splitNewlines(afterFooter));
|
11235 |
+
return lines;
|
11236 |
+
}
|
11237 |
+
_createItems(options) {
|
11238 |
+
const active = this._active;
|
11239 |
+
const data = this.chart.data;
|
11240 |
+
const labelColors = [];
|
11241 |
+
const labelPointStyles = [];
|
11242 |
+
const labelTextColors = [];
|
11243 |
+
let tooltipItems = [];
|
11244 |
+
let i, len;
|
11245 |
+
for (i = 0, len = active.length; i < len; ++i) {
|
11246 |
+
tooltipItems.push(createTooltipItem(this.chart, active[i]));
|
11247 |
+
}
|
11248 |
+
if (options.filter) {
|
11249 |
+
tooltipItems = tooltipItems.filter((element, index, array) => options.filter(element, index, array, data));
|
11250 |
+
}
|
11251 |
+
if (options.itemSort) {
|
11252 |
+
tooltipItems = tooltipItems.sort((a, b) => options.itemSort(a, b, data));
|
11253 |
+
}
|
11254 |
+
each(tooltipItems, (context) => {
|
11255 |
+
const scoped = overrideCallbacks(options.callbacks, context);
|
11256 |
+
labelColors.push(scoped.labelColor.call(this, context));
|
11257 |
+
labelPointStyles.push(scoped.labelPointStyle.call(this, context));
|
11258 |
+
labelTextColors.push(scoped.labelTextColor.call(this, context));
|
11259 |
+
});
|
11260 |
+
this.labelColors = labelColors;
|
11261 |
+
this.labelPointStyles = labelPointStyles;
|
11262 |
+
this.labelTextColors = labelTextColors;
|
11263 |
+
this.dataPoints = tooltipItems;
|
11264 |
+
return tooltipItems;
|
11265 |
+
}
|
11266 |
+
update(changed, replay) {
|
11267 |
+
const options = this.options.setContext(this.getContext());
|
11268 |
+
const active = this._active;
|
11269 |
+
let properties;
|
11270 |
+
let tooltipItems = [];
|
11271 |
+
if (!active.length) {
|
11272 |
+
if (this.opacity !== 0) {
|
11273 |
+
properties = {
|
11274 |
+
opacity: 0
|
11275 |
+
};
|
11276 |
+
}
|
11277 |
+
} else {
|
11278 |
+
const position = positioners[options.position].call(this, active, this._eventPosition);
|
11279 |
+
tooltipItems = this._createItems(options);
|
11280 |
+
this.title = this.getTitle(tooltipItems, options);
|
11281 |
+
this.beforeBody = this.getBeforeBody(tooltipItems, options);
|
11282 |
+
this.body = this.getBody(tooltipItems, options);
|
11283 |
+
this.afterBody = this.getAfterBody(tooltipItems, options);
|
11284 |
+
this.footer = this.getFooter(tooltipItems, options);
|
11285 |
+
const size = this._size = getTooltipSize(this, options);
|
11286 |
+
const positionAndSize = Object.assign({}, position, size);
|
11287 |
+
const alignment = determineAlignment(this.chart, options, positionAndSize);
|
11288 |
+
const backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart);
|
11289 |
+
this.xAlign = alignment.xAlign;
|
11290 |
+
this.yAlign = alignment.yAlign;
|
11291 |
+
properties = {
|
11292 |
+
opacity: 1,
|
11293 |
+
x: backgroundPoint.x,
|
11294 |
+
y: backgroundPoint.y,
|
11295 |
+
width: size.width,
|
11296 |
+
height: size.height,
|
11297 |
+
caretX: position.x,
|
11298 |
+
caretY: position.y
|
11299 |
+
};
|
11300 |
+
}
|
11301 |
+
this._tooltipItems = tooltipItems;
|
11302 |
+
this.$context = undefined;
|
11303 |
+
if (properties) {
|
11304 |
+
this._resolveAnimations().update(this, properties);
|
11305 |
+
}
|
11306 |
+
if (changed && options.external) {
|
11307 |
+
options.external.call(this, {chart: this.chart, tooltip: this, replay});
|
11308 |
+
}
|
11309 |
+
}
|
11310 |
+
drawCaret(tooltipPoint, ctx, size, options) {
|
11311 |
+
const caretPosition = this.getCaretPosition(tooltipPoint, size, options);
|
11312 |
+
ctx.lineTo(caretPosition.x1, caretPosition.y1);
|
11313 |
+
ctx.lineTo(caretPosition.x2, caretPosition.y2);
|
11314 |
+
ctx.lineTo(caretPosition.x3, caretPosition.y3);
|
11315 |
+
}
|
11316 |
+
getCaretPosition(tooltipPoint, size, options) {
|
11317 |
+
const {xAlign, yAlign} = this;
|
11318 |
+
const {caretSize, cornerRadius} = options;
|
11319 |
+
const {topLeft, topRight, bottomLeft, bottomRight} = toTRBLCorners(cornerRadius);
|
11320 |
+
const {x: ptX, y: ptY} = tooltipPoint;
|
11321 |
+
const {width, height} = size;
|
11322 |
+
let x1, x2, x3, y1, y2, y3;
|
11323 |
+
if (yAlign === 'center') {
|
11324 |
+
y2 = ptY + (height / 2);
|
11325 |
+
if (xAlign === 'left') {
|
11326 |
+
x1 = ptX;
|
11327 |
+
x2 = x1 - caretSize;
|
11328 |
+
y1 = y2 + caretSize;
|
11329 |
+
y3 = y2 - caretSize;
|
11330 |
+
} else {
|
11331 |
+
x1 = ptX + width;
|
11332 |
+
x2 = x1 + caretSize;
|
11333 |
+
y1 = y2 - caretSize;
|
11334 |
+
y3 = y2 + caretSize;
|
11335 |
+
}
|
11336 |
+
x3 = x1;
|
11337 |
+
} else {
|
11338 |
+
if (xAlign === 'left') {
|
11339 |
+
x2 = ptX + Math.max(topLeft, bottomLeft) + (caretSize);
|
11340 |
+
} else if (xAlign === 'right') {
|
11341 |
+
x2 = ptX + width - Math.max(topRight, bottomRight) - caretSize;
|
11342 |
+
} else {
|
11343 |
+
x2 = this.caretX;
|
11344 |
+
}
|
11345 |
+
if (yAlign === 'top') {
|
11346 |
+
y1 = ptY;
|
11347 |
+
y2 = y1 - caretSize;
|
11348 |
+
x1 = x2 - caretSize;
|
11349 |
+
x3 = x2 + caretSize;
|
11350 |
+
} else {
|
11351 |
+
y1 = ptY + height;
|
11352 |
+
y2 = y1 + caretSize;
|
11353 |
+
x1 = x2 + caretSize;
|
11354 |
+
x3 = x2 - caretSize;
|
11355 |
+
}
|
11356 |
+
y3 = y1;
|
11357 |
+
}
|
11358 |
+
return {x1, x2, x3, y1, y2, y3};
|
11359 |
+
}
|
11360 |
+
drawTitle(pt, ctx, options) {
|
11361 |
+
const title = this.title;
|
11362 |
+
const length = title.length;
|
11363 |
+
let titleFont, titleSpacing, i;
|
11364 |
+
if (length) {
|
11365 |
+
const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
|
11366 |
+
pt.x = getAlignedX(this, options.titleAlign, options);
|
11367 |
+
ctx.textAlign = rtlHelper.textAlign(options.titleAlign);
|
11368 |
+
ctx.textBaseline = 'middle';
|
11369 |
+
titleFont = toFont(options.titleFont);
|
11370 |
+
titleSpacing = options.titleSpacing;
|
11371 |
+
ctx.fillStyle = options.titleColor;
|
11372 |
+
ctx.font = titleFont.string;
|
11373 |
+
for (i = 0; i < length; ++i) {
|
11374 |
+
ctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFont.lineHeight / 2);
|
11375 |
+
pt.y += titleFont.lineHeight + titleSpacing;
|
11376 |
+
if (i + 1 === length) {
|
11377 |
+
pt.y += options.titleMarginBottom - titleSpacing;
|
11378 |
+
}
|
11379 |
+
}
|
11380 |
+
}
|
11381 |
+
}
|
11382 |
+
_drawColorBox(ctx, pt, i, rtlHelper, options) {
|
11383 |
+
const labelColors = this.labelColors[i];
|
11384 |
+
const labelPointStyle = this.labelPointStyles[i];
|
11385 |
+
const {boxHeight, boxWidth, boxPadding} = options;
|
11386 |
+
const bodyFont = toFont(options.bodyFont);
|
11387 |
+
const colorX = getAlignedX(this, 'left', options);
|
11388 |
+
const rtlColorX = rtlHelper.x(colorX);
|
11389 |
+
const yOffSet = boxHeight < bodyFont.lineHeight ? (bodyFont.lineHeight - boxHeight) / 2 : 0;
|
11390 |
+
const colorY = pt.y + yOffSet;
|
11391 |
+
if (options.usePointStyle) {
|
11392 |
+
const drawOptions = {
|
11393 |
+
radius: Math.min(boxWidth, boxHeight) / 2,
|
11394 |
+
pointStyle: labelPointStyle.pointStyle,
|
11395 |
+
rotation: labelPointStyle.rotation,
|
11396 |
+
borderWidth: 1
|
11397 |
+
};
|
11398 |
+
const centerX = rtlHelper.leftForLtr(rtlColorX, boxWidth) + boxWidth / 2;
|
11399 |
+
const centerY = colorY + boxHeight / 2;
|
11400 |
+
ctx.strokeStyle = options.multiKeyBackground;
|
11401 |
+
ctx.fillStyle = options.multiKeyBackground;
|
11402 |
+
drawPoint(ctx, drawOptions, centerX, centerY);
|
11403 |
+
ctx.strokeStyle = labelColors.borderColor;
|
11404 |
+
ctx.fillStyle = labelColors.backgroundColor;
|
11405 |
+
drawPoint(ctx, drawOptions, centerX, centerY);
|
11406 |
+
} else {
|
11407 |
+
ctx.lineWidth = labelColors.borderWidth || 1;
|
11408 |
+
ctx.strokeStyle = labelColors.borderColor;
|
11409 |
+
ctx.setLineDash(labelColors.borderDash || []);
|
11410 |
+
ctx.lineDashOffset = labelColors.borderDashOffset || 0;
|
11411 |
+
const outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth - boxPadding);
|
11412 |
+
const innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - boxPadding - 2);
|
11413 |
+
const borderRadius = toTRBLCorners(labelColors.borderRadius);
|
11414 |
+
if (Object.values(borderRadius).some(v => v !== 0)) {
|
11415 |
+
ctx.beginPath();
|
11416 |
+
ctx.fillStyle = options.multiKeyBackground;
|
11417 |
+
addRoundedRectPath(ctx, {
|
11418 |
+
x: outerX,
|
11419 |
+
y: colorY,
|
11420 |
+
w: boxWidth,
|
11421 |
+
h: boxHeight,
|
11422 |
+
radius: borderRadius,
|
11423 |
+
});
|
11424 |
+
ctx.fill();
|
11425 |
+
ctx.stroke();
|
11426 |
+
ctx.fillStyle = labelColors.backgroundColor;
|
11427 |
+
ctx.beginPath();
|
11428 |
+
addRoundedRectPath(ctx, {
|
11429 |
+
x: innerX,
|
11430 |
+
y: colorY + 1,
|
11431 |
+
w: boxWidth - 2,
|
11432 |
+
h: boxHeight - 2,
|
11433 |
+
radius: borderRadius,
|
11434 |
+
});
|
11435 |
+
ctx.fill();
|
11436 |
+
} else {
|
11437 |
+
ctx.fillStyle = options.multiKeyBackground;
|
11438 |
+
ctx.fillRect(outerX, colorY, boxWidth, boxHeight);
|
11439 |
+
ctx.strokeRect(outerX, colorY, boxWidth, boxHeight);
|
11440 |
+
ctx.fillStyle = labelColors.backgroundColor;
|
11441 |
+
ctx.fillRect(innerX, colorY + 1, boxWidth - 2, boxHeight - 2);
|
11442 |
+
}
|
11443 |
+
}
|
11444 |
+
ctx.fillStyle = this.labelTextColors[i];
|
11445 |
+
}
|
11446 |
+
drawBody(pt, ctx, options) {
|
11447 |
+
const {body} = this;
|
11448 |
+
const {bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth, boxPadding} = options;
|
11449 |
+
const bodyFont = toFont(options.bodyFont);
|
11450 |
+
let bodyLineHeight = bodyFont.lineHeight;
|
11451 |
+
let xLinePadding = 0;
|
11452 |
+
const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
|
11453 |
+
const fillLineOfText = function(line) {
|
11454 |
+
ctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyLineHeight / 2);
|
11455 |
+
pt.y += bodyLineHeight + bodySpacing;
|
11456 |
+
};
|
11457 |
+
const bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign);
|
11458 |
+
let bodyItem, textColor, lines, i, j, ilen, jlen;
|
11459 |
+
ctx.textAlign = bodyAlign;
|
11460 |
+
ctx.textBaseline = 'middle';
|
11461 |
+
ctx.font = bodyFont.string;
|
11462 |
+
pt.x = getAlignedX(this, bodyAlignForCalculation, options);
|
11463 |
+
ctx.fillStyle = options.bodyColor;
|
11464 |
+
each(this.beforeBody, fillLineOfText);
|
11465 |
+
xLinePadding = displayColors && bodyAlignForCalculation !== 'right'
|
11466 |
+
? bodyAlign === 'center' ? (boxWidth / 2 + boxPadding) : (boxWidth + 2 + boxPadding)
|
11467 |
+
: 0;
|
11468 |
+
for (i = 0, ilen = body.length; i < ilen; ++i) {
|
11469 |
+
bodyItem = body[i];
|
11470 |
+
textColor = this.labelTextColors[i];
|
11471 |
+
ctx.fillStyle = textColor;
|
11472 |
+
each(bodyItem.before, fillLineOfText);
|
11473 |
+
lines = bodyItem.lines;
|
11474 |
+
if (displayColors && lines.length) {
|
11475 |
+
this._drawColorBox(ctx, pt, i, rtlHelper, options);
|
11476 |
+
bodyLineHeight = Math.max(bodyFont.lineHeight, boxHeight);
|
11477 |
+
}
|
11478 |
+
for (j = 0, jlen = lines.length; j < jlen; ++j) {
|
11479 |
+
fillLineOfText(lines[j]);
|
11480 |
+
bodyLineHeight = bodyFont.lineHeight;
|
11481 |
+
}
|
11482 |
+
each(bodyItem.after, fillLineOfText);
|
11483 |
+
}
|
11484 |
+
xLinePadding = 0;
|
11485 |
+
bodyLineHeight = bodyFont.lineHeight;
|
11486 |
+
each(this.afterBody, fillLineOfText);
|
11487 |
+
pt.y -= bodySpacing;
|
11488 |
+
}
|
11489 |
+
drawFooter(pt, ctx, options) {
|
11490 |
+
const footer = this.footer;
|
11491 |
+
const length = footer.length;
|
11492 |
+
let footerFont, i;
|
11493 |
+
if (length) {
|
11494 |
+
const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
|
11495 |
+
pt.x = getAlignedX(this, options.footerAlign, options);
|
11496 |
+
pt.y += options.footerMarginTop;
|
11497 |
+
ctx.textAlign = rtlHelper.textAlign(options.footerAlign);
|
11498 |
+
ctx.textBaseline = 'middle';
|
11499 |
+
footerFont = toFont(options.footerFont);
|
11500 |
+
ctx.fillStyle = options.footerColor;
|
11501 |
+
ctx.font = footerFont.string;
|
11502 |
+
for (i = 0; i < length; ++i) {
|
11503 |
+
ctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFont.lineHeight / 2);
|
11504 |
+
pt.y += footerFont.lineHeight + options.footerSpacing;
|
11505 |
+
}
|
11506 |
+
}
|
11507 |
+
}
|
11508 |
+
drawBackground(pt, ctx, tooltipSize, options) {
|
11509 |
+
const {xAlign, yAlign} = this;
|
11510 |
+
const {x, y} = pt;
|
11511 |
+
const {width, height} = tooltipSize;
|
11512 |
+
const {topLeft, topRight, bottomLeft, bottomRight} = toTRBLCorners(options.cornerRadius);
|
11513 |
+
ctx.fillStyle = options.backgroundColor;
|
11514 |
+
ctx.strokeStyle = options.borderColor;
|
11515 |
+
ctx.lineWidth = options.borderWidth;
|
11516 |
+
ctx.beginPath();
|
11517 |
+
ctx.moveTo(x + topLeft, y);
|
11518 |
+
if (yAlign === 'top') {
|
11519 |
+
this.drawCaret(pt, ctx, tooltipSize, options);
|
11520 |
+
}
|
11521 |
+
ctx.lineTo(x + width - topRight, y);
|
11522 |
+
ctx.quadraticCurveTo(x + width, y, x + width, y + topRight);
|
11523 |
+
if (yAlign === 'center' && xAlign === 'right') {
|
11524 |
+
this.drawCaret(pt, ctx, tooltipSize, options);
|
11525 |
+
}
|
11526 |
+
ctx.lineTo(x + width, y + height - bottomRight);
|
11527 |
+
ctx.quadraticCurveTo(x + width, y + height, x + width - bottomRight, y + height);
|
11528 |
+
if (yAlign === 'bottom') {
|
11529 |
+
this.drawCaret(pt, ctx, tooltipSize, options);
|
11530 |
+
}
|
11531 |
+
ctx.lineTo(x + bottomLeft, y + height);
|
11532 |
+
ctx.quadraticCurveTo(x, y + height, x, y + height - bottomLeft);
|
11533 |
+
if (yAlign === 'center' && xAlign === 'left') {
|
11534 |
+
this.drawCaret(pt, ctx, tooltipSize, options);
|
11535 |
+
}
|
11536 |
+
ctx.lineTo(x, y + topLeft);
|
11537 |
+
ctx.quadraticCurveTo(x, y, x + topLeft, y);
|
11538 |
+
ctx.closePath();
|
11539 |
+
ctx.fill();
|
11540 |
+
if (options.borderWidth > 0) {
|
11541 |
+
ctx.stroke();
|
11542 |
+
}
|
11543 |
+
}
|
11544 |
+
_updateAnimationTarget(options) {
|
11545 |
+
const chart = this.chart;
|
11546 |
+
const anims = this.$animations;
|
11547 |
+
const animX = anims && anims.x;
|
11548 |
+
const animY = anims && anims.y;
|
11549 |
+
if (animX || animY) {
|
11550 |
+
const position = positioners[options.position].call(this, this._active, this._eventPosition);
|
11551 |
+
if (!position) {
|
11552 |
+
return;
|
11553 |
+
}
|
11554 |
+
const size = this._size = getTooltipSize(this, options);
|
11555 |
+
const positionAndSize = Object.assign({}, position, this._size);
|
11556 |
+
const alignment = determineAlignment(chart, options, positionAndSize);
|
11557 |
+
const point = getBackgroundPoint(options, positionAndSize, alignment, chart);
|
11558 |
+
if (animX._to !== point.x || animY._to !== point.y) {
|
11559 |
+
this.xAlign = alignment.xAlign;
|
11560 |
+
this.yAlign = alignment.yAlign;
|
11561 |
+
this.width = size.width;
|
11562 |
+
this.height = size.height;
|
11563 |
+
this.caretX = position.x;
|
11564 |
+
this.caretY = position.y;
|
11565 |
+
this._resolveAnimations().update(this, point);
|
11566 |
+
}
|
11567 |
+
}
|
11568 |
+
}
|
11569 |
+
draw(ctx) {
|
11570 |
+
const options = this.options.setContext(this.getContext());
|
11571 |
+
let opacity = this.opacity;
|
11572 |
+
if (!opacity) {
|
11573 |
+
return;
|
11574 |
+
}
|
11575 |
+
this._updateAnimationTarget(options);
|
11576 |
+
const tooltipSize = {
|
11577 |
+
width: this.width,
|
11578 |
+
height: this.height
|
11579 |
+
};
|
11580 |
+
const pt = {
|
11581 |
+
x: this.x,
|
11582 |
+
y: this.y
|
11583 |
+
};
|
11584 |
+
opacity = Math.abs(opacity) < 1e-3 ? 0 : opacity;
|
11585 |
+
const padding = toPadding(options.padding);
|
11586 |
+
const hasTooltipContent = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length;
|
11587 |
+
if (options.enabled && hasTooltipContent) {
|
11588 |
+
ctx.save();
|
11589 |
+
ctx.globalAlpha = opacity;
|
11590 |
+
this.drawBackground(pt, ctx, tooltipSize, options);
|
11591 |
+
overrideTextDirection(ctx, options.textDirection);
|
11592 |
+
pt.y += padding.top;
|
11593 |
+
this.drawTitle(pt, ctx, options);
|
11594 |
+
this.drawBody(pt, ctx, options);
|
11595 |
+
this.drawFooter(pt, ctx, options);
|
11596 |
+
restoreTextDirection(ctx, options.textDirection);
|
11597 |
+
ctx.restore();
|
11598 |
+
}
|
11599 |
+
}
|
11600 |
+
getActiveElements() {
|
11601 |
+
return this._active || [];
|
11602 |
+
}
|
11603 |
+
setActiveElements(activeElements, eventPosition) {
|
11604 |
+
const lastActive = this._active;
|
11605 |
+
const active = activeElements.map(({datasetIndex, index}) => {
|
11606 |
+
const meta = this.chart.getDatasetMeta(datasetIndex);
|
11607 |
+
if (!meta) {
|
11608 |
+
throw new Error('Cannot find a dataset at index ' + datasetIndex);
|
11609 |
+
}
|
11610 |
+
return {
|
11611 |
+
datasetIndex,
|
11612 |
+
element: meta.data[index],
|
11613 |
+
index,
|
11614 |
+
};
|
11615 |
+
});
|
11616 |
+
const changed = !_elementsEqual(lastActive, active);
|
11617 |
+
const positionChanged = this._positionChanged(active, eventPosition);
|
11618 |
+
if (changed || positionChanged) {
|
11619 |
+
this._active = active;
|
11620 |
+
this._eventPosition = eventPosition;
|
11621 |
+
this._ignoreReplayEvents = true;
|
11622 |
+
this.update(true);
|
11623 |
+
}
|
11624 |
+
}
|
11625 |
+
handleEvent(e, replay, inChartArea = true) {
|
11626 |
+
if (replay && this._ignoreReplayEvents) {
|
11627 |
+
return false;
|
11628 |
+
}
|
11629 |
+
this._ignoreReplayEvents = false;
|
11630 |
+
const options = this.options;
|
11631 |
+
const lastActive = this._active || [];
|
11632 |
+
const active = this._getActiveElements(e, lastActive, replay, inChartArea);
|
11633 |
+
const positionChanged = this._positionChanged(active, e);
|
11634 |
+
const changed = replay || !_elementsEqual(active, lastActive) || positionChanged;
|
11635 |
+
if (changed) {
|
11636 |
+
this._active = active;
|
11637 |
+
if (options.enabled || options.external) {
|
11638 |
+
this._eventPosition = {
|
11639 |
+
x: e.x,
|
11640 |
+
y: e.y
|
11641 |
+
};
|
11642 |
+
this.update(true, replay);
|
11643 |
+
}
|
11644 |
+
}
|
11645 |
+
return changed;
|
11646 |
+
}
|
11647 |
+
_getActiveElements(e, lastActive, replay, inChartArea) {
|
11648 |
+
const options = this.options;
|
11649 |
+
if (e.type === 'mouseout') {
|
11650 |
+
return [];
|
11651 |
+
}
|
11652 |
+
if (!inChartArea) {
|
11653 |
+
return lastActive;
|
11654 |
+
}
|
11655 |
+
const active = this.chart.getElementsAtEventForMode(e, options.mode, options, replay);
|
11656 |
+
if (options.reverse) {
|
11657 |
+
active.reverse();
|
11658 |
+
}
|
11659 |
+
return active;
|
11660 |
+
}
|
11661 |
+
_positionChanged(active, e) {
|
11662 |
+
const {caretX, caretY, options} = this;
|
11663 |
+
const position = positioners[options.position].call(this, active, e);
|
11664 |
+
return position !== false && (caretX !== position.x || caretY !== position.y);
|
11665 |
+
}
|
11666 |
+
}
|
11667 |
+
Tooltip.positioners = positioners;
|
11668 |
+
var plugin_tooltip = {
|
11669 |
+
id: 'tooltip',
|
11670 |
+
_element: Tooltip,
|
11671 |
+
positioners,
|
11672 |
+
afterInit(chart, _args, options) {
|
11673 |
+
if (options) {
|
11674 |
+
chart.tooltip = new Tooltip({chart, options});
|
11675 |
+
}
|
11676 |
+
},
|
11677 |
+
beforeUpdate(chart, _args, options) {
|
11678 |
+
if (chart.tooltip) {
|
11679 |
+
chart.tooltip.initialize(options);
|
11680 |
+
}
|
11681 |
+
},
|
11682 |
+
reset(chart, _args, options) {
|
11683 |
+
if (chart.tooltip) {
|
11684 |
+
chart.tooltip.initialize(options);
|
11685 |
+
}
|
11686 |
+
},
|
11687 |
+
afterDraw(chart) {
|
11688 |
+
const tooltip = chart.tooltip;
|
11689 |
+
const args = {
|
11690 |
+
tooltip
|
11691 |
+
};
|
11692 |
+
if (chart.notifyPlugins('beforeTooltipDraw', args) === false) {
|
11693 |
+
return;
|
11694 |
+
}
|
11695 |
+
if (tooltip) {
|
11696 |
+
tooltip.draw(chart.ctx);
|
11697 |
+
}
|
11698 |
+
chart.notifyPlugins('afterTooltipDraw', args);
|
11699 |
+
},
|
11700 |
+
afterEvent(chart, args) {
|
11701 |
+
if (chart.tooltip) {
|
11702 |
+
const useFinalPosition = args.replay;
|
11703 |
+
if (chart.tooltip.handleEvent(args.event, useFinalPosition, args.inChartArea)) {
|
11704 |
+
args.changed = true;
|
11705 |
+
}
|
11706 |
+
}
|
11707 |
+
},
|
11708 |
+
defaults: {
|
11709 |
+
enabled: true,
|
11710 |
+
external: null,
|
11711 |
+
position: 'average',
|
11712 |
+
backgroundColor: 'rgba(0,0,0,0.8)',
|
11713 |
+
titleColor: '#fff',
|
11714 |
+
titleFont: {
|
11715 |
+
weight: 'bold',
|
11716 |
+
},
|
11717 |
+
titleSpacing: 2,
|
11718 |
+
titleMarginBottom: 6,
|
11719 |
+
titleAlign: 'left',
|
11720 |
+
bodyColor: '#fff',
|
11721 |
+
bodySpacing: 2,
|
11722 |
+
bodyFont: {
|
11723 |
+
},
|
11724 |
+
bodyAlign: 'left',
|
11725 |
+
footerColor: '#fff',
|
11726 |
+
footerSpacing: 2,
|
11727 |
+
footerMarginTop: 6,
|
11728 |
+
footerFont: {
|
11729 |
+
weight: 'bold',
|
11730 |
+
},
|
11731 |
+
footerAlign: 'left',
|
11732 |
+
padding: 6,
|
11733 |
+
caretPadding: 2,
|
11734 |
+
caretSize: 5,
|
11735 |
+
cornerRadius: 6,
|
11736 |
+
boxHeight: (ctx, opts) => opts.bodyFont.size,
|
11737 |
+
boxWidth: (ctx, opts) => opts.bodyFont.size,
|
11738 |
+
multiKeyBackground: '#fff',
|
11739 |
+
displayColors: true,
|
11740 |
+
boxPadding: 0,
|
11741 |
+
borderColor: 'rgba(0,0,0,0)',
|
11742 |
+
borderWidth: 0,
|
11743 |
+
animation: {
|
11744 |
+
duration: 400,
|
11745 |
+
easing: 'easeOutQuart',
|
11746 |
+
},
|
11747 |
+
animations: {
|
11748 |
+
numbers: {
|
11749 |
+
type: 'number',
|
11750 |
+
properties: ['x', 'y', 'width', 'height', 'caretX', 'caretY'],
|
11751 |
+
},
|
11752 |
+
opacity: {
|
11753 |
+
easing: 'linear',
|
11754 |
+
duration: 200
|
11755 |
+
}
|
11756 |
+
},
|
11757 |
+
callbacks: {
|
11758 |
+
beforeTitle: noop,
|
11759 |
+
title(tooltipItems) {
|
11760 |
+
if (tooltipItems.length > 0) {
|
11761 |
+
const item = tooltipItems[0];
|
11762 |
+
const labels = item.chart.data.labels;
|
11763 |
+
const labelCount = labels ? labels.length : 0;
|
11764 |
+
if (this && this.options && this.options.mode === 'dataset') {
|
11765 |
+
return item.dataset.label || '';
|
11766 |
+
} else if (item.label) {
|
11767 |
+
return item.label;
|
11768 |
+
} else if (labelCount > 0 && item.dataIndex < labelCount) {
|
11769 |
+
return labels[item.dataIndex];
|
11770 |
+
}
|
11771 |
+
}
|
11772 |
+
return '';
|
11773 |
+
},
|
11774 |
+
afterTitle: noop,
|
11775 |
+
beforeBody: noop,
|
11776 |
+
beforeLabel: noop,
|
11777 |
+
label(tooltipItem) {
|
11778 |
+
if (this && this.options && this.options.mode === 'dataset') {
|
11779 |
+
return tooltipItem.label + ': ' + tooltipItem.formattedValue || tooltipItem.formattedValue;
|
11780 |
+
}
|
11781 |
+
let label = tooltipItem.dataset.label || '';
|
11782 |
+
if (label) {
|
11783 |
+
label += ': ';
|
11784 |
+
}
|
11785 |
+
const value = tooltipItem.formattedValue;
|
11786 |
+
if (!isNullOrUndef(value)) {
|
11787 |
+
label += value;
|
11788 |
+
}
|
11789 |
+
return label;
|
11790 |
+
},
|
11791 |
+
labelColor(tooltipItem) {
|
11792 |
+
const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex);
|
11793 |
+
const options = meta.controller.getStyle(tooltipItem.dataIndex);
|
11794 |
+
return {
|
11795 |
+
borderColor: options.borderColor,
|
11796 |
+
backgroundColor: options.backgroundColor,
|
11797 |
+
borderWidth: options.borderWidth,
|
11798 |
+
borderDash: options.borderDash,
|
11799 |
+
borderDashOffset: options.borderDashOffset,
|
11800 |
+
borderRadius: 0,
|
11801 |
+
};
|
11802 |
+
},
|
11803 |
+
labelTextColor() {
|
11804 |
+
return this.options.bodyColor;
|
11805 |
+
},
|
11806 |
+
labelPointStyle(tooltipItem) {
|
11807 |
+
const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex);
|
11808 |
+
const options = meta.controller.getStyle(tooltipItem.dataIndex);
|
11809 |
+
return {
|
11810 |
+
pointStyle: options.pointStyle,
|
11811 |
+
rotation: options.rotation,
|
11812 |
+
};
|
11813 |
+
},
|
11814 |
+
afterLabel: noop,
|
11815 |
+
afterBody: noop,
|
11816 |
+
beforeFooter: noop,
|
11817 |
+
footer: noop,
|
11818 |
+
afterFooter: noop
|
11819 |
+
}
|
11820 |
+
},
|
11821 |
+
defaultRoutes: {
|
11822 |
+
bodyFont: 'font',
|
11823 |
+
footerFont: 'font',
|
11824 |
+
titleFont: 'font'
|
11825 |
+
},
|
11826 |
+
descriptors: {
|
11827 |
+
_scriptable: (name) => name !== 'filter' && name !== 'itemSort' && name !== 'external',
|
11828 |
+
_indexable: false,
|
11829 |
+
callbacks: {
|
11830 |
+
_scriptable: false,
|
11831 |
+
_indexable: false,
|
11832 |
+
},
|
11833 |
+
animation: {
|
11834 |
+
_fallback: false
|
11835 |
+
},
|
11836 |
+
animations: {
|
11837 |
+
_fallback: 'animation'
|
11838 |
+
}
|
11839 |
+
},
|
11840 |
+
additionalOptionScopes: ['interaction']
|
11841 |
+
};
|
11842 |
+
|
11843 |
+
var plugins = /*#__PURE__*/Object.freeze({
|
11844 |
+
__proto__: null,
|
11845 |
+
Decimation: plugin_decimation,
|
11846 |
+
Filler: plugin_filler,
|
11847 |
+
Legend: plugin_legend,
|
11848 |
+
SubTitle: plugin_subtitle,
|
11849 |
+
Title: plugin_title,
|
11850 |
+
Tooltip: plugin_tooltip
|
11851 |
+
});
|
11852 |
+
|
11853 |
+
const addIfString = (labels, raw, index, addedLabels) => {
|
11854 |
+
if (typeof raw === 'string') {
|
11855 |
+
index = labels.push(raw) - 1;
|
11856 |
+
addedLabels.unshift({index, label: raw});
|
11857 |
+
} else if (isNaN(raw)) {
|
11858 |
+
index = null;
|
11859 |
+
}
|
11860 |
+
return index;
|
11861 |
+
};
|
11862 |
+
function findOrAddLabel(labels, raw, index, addedLabels) {
|
11863 |
+
const first = labels.indexOf(raw);
|
11864 |
+
if (first === -1) {
|
11865 |
+
return addIfString(labels, raw, index, addedLabels);
|
11866 |
+
}
|
11867 |
+
const last = labels.lastIndexOf(raw);
|
11868 |
+
return first !== last ? index : first;
|
11869 |
+
}
|
11870 |
+
const validIndex = (index, max) => index === null ? null : _limitValue(Math.round(index), 0, max);
|
11871 |
+
class CategoryScale extends Scale {
|
11872 |
+
constructor(cfg) {
|
11873 |
+
super(cfg);
|
11874 |
+
this._startValue = undefined;
|
11875 |
+
this._valueRange = 0;
|
11876 |
+
this._addedLabels = [];
|
11877 |
+
}
|
11878 |
+
init(scaleOptions) {
|
11879 |
+
const added = this._addedLabels;
|
11880 |
+
if (added.length) {
|
11881 |
+
const labels = this.getLabels();
|
11882 |
+
for (const {index, label} of added) {
|
11883 |
+
if (labels[index] === label) {
|
11884 |
+
labels.splice(index, 1);
|
11885 |
+
}
|
11886 |
+
}
|
11887 |
+
this._addedLabels = [];
|
11888 |
+
}
|
11889 |
+
super.init(scaleOptions);
|
11890 |
+
}
|
11891 |
+
parse(raw, index) {
|
11892 |
+
if (isNullOrUndef(raw)) {
|
11893 |
+
return null;
|
11894 |
+
}
|
11895 |
+
const labels = this.getLabels();
|
11896 |
+
index = isFinite(index) && labels[index] === raw ? index
|
11897 |
+
: findOrAddLabel(labels, raw, valueOrDefault(index, raw), this._addedLabels);
|
11898 |
+
return validIndex(index, labels.length - 1);
|
11899 |
+
}
|
11900 |
+
determineDataLimits() {
|
11901 |
+
const {minDefined, maxDefined} = this.getUserBounds();
|
11902 |
+
let {min, max} = this.getMinMax(true);
|
11903 |
+
if (this.options.bounds === 'ticks') {
|
11904 |
+
if (!minDefined) {
|
11905 |
+
min = 0;
|
11906 |
+
}
|
11907 |
+
if (!maxDefined) {
|
11908 |
+
max = this.getLabels().length - 1;
|
11909 |
+
}
|
11910 |
+
}
|
11911 |
+
this.min = min;
|
11912 |
+
this.max = max;
|
11913 |
+
}
|
11914 |
+
buildTicks() {
|
11915 |
+
const min = this.min;
|
11916 |
+
const max = this.max;
|
11917 |
+
const offset = this.options.offset;
|
11918 |
+
const ticks = [];
|
11919 |
+
let labels = this.getLabels();
|
11920 |
+
labels = (min === 0 && max === labels.length - 1) ? labels : labels.slice(min, max + 1);
|
11921 |
+
this._valueRange = Math.max(labels.length - (offset ? 0 : 1), 1);
|
11922 |
+
this._startValue = this.min - (offset ? 0.5 : 0);
|
11923 |
+
for (let value = min; value <= max; value++) {
|
11924 |
+
ticks.push({value});
|
11925 |
+
}
|
11926 |
+
return ticks;
|
11927 |
+
}
|
11928 |
+
getLabelForValue(value) {
|
11929 |
+
const labels = this.getLabels();
|
11930 |
+
if (value >= 0 && value < labels.length) {
|
11931 |
+
return labels[value];
|
11932 |
+
}
|
11933 |
+
return value;
|
11934 |
+
}
|
11935 |
+
configure() {
|
11936 |
+
super.configure();
|
11937 |
+
if (!this.isHorizontal()) {
|
11938 |
+
this._reversePixels = !this._reversePixels;
|
11939 |
+
}
|
11940 |
+
}
|
11941 |
+
getPixelForValue(value) {
|
11942 |
+
if (typeof value !== 'number') {
|
11943 |
+
value = this.parse(value);
|
11944 |
+
}
|
11945 |
+
return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange);
|
11946 |
+
}
|
11947 |
+
getPixelForTick(index) {
|
11948 |
+
const ticks = this.ticks;
|
11949 |
+
if (index < 0 || index > ticks.length - 1) {
|
11950 |
+
return null;
|
11951 |
+
}
|
11952 |
+
return this.getPixelForValue(ticks[index].value);
|
11953 |
+
}
|
11954 |
+
getValueForPixel(pixel) {
|
11955 |
+
return Math.round(this._startValue + this.getDecimalForPixel(pixel) * this._valueRange);
|
11956 |
+
}
|
11957 |
+
getBasePixel() {
|
11958 |
+
return this.bottom;
|
11959 |
+
}
|
11960 |
+
}
|
11961 |
+
CategoryScale.id = 'category';
|
11962 |
+
CategoryScale.defaults = {
|
11963 |
+
ticks: {
|
11964 |
+
callback: CategoryScale.prototype.getLabelForValue
|
11965 |
+
}
|
11966 |
+
};
|
11967 |
+
|
11968 |
+
function generateTicks$1(generationOptions, dataRange) {
|
11969 |
+
const ticks = [];
|
11970 |
+
const MIN_SPACING = 1e-14;
|
11971 |
+
const {bounds, step, min, max, precision, count, maxTicks, maxDigits, includeBounds} = generationOptions;
|
11972 |
+
const unit = step || 1;
|
11973 |
+
const maxSpaces = maxTicks - 1;
|
11974 |
+
const {min: rmin, max: rmax} = dataRange;
|
11975 |
+
const minDefined = !isNullOrUndef(min);
|
11976 |
+
const maxDefined = !isNullOrUndef(max);
|
11977 |
+
const countDefined = !isNullOrUndef(count);
|
11978 |
+
const minSpacing = (rmax - rmin) / (maxDigits + 1);
|
11979 |
+
let spacing = niceNum((rmax - rmin) / maxSpaces / unit) * unit;
|
11980 |
+
let factor, niceMin, niceMax, numSpaces;
|
11981 |
+
if (spacing < MIN_SPACING && !minDefined && !maxDefined) {
|
11982 |
+
return [{value: rmin}, {value: rmax}];
|
11983 |
+
}
|
11984 |
+
numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing);
|
11985 |
+
if (numSpaces > maxSpaces) {
|
11986 |
+
spacing = niceNum(numSpaces * spacing / maxSpaces / unit) * unit;
|
11987 |
+
}
|
11988 |
+
if (!isNullOrUndef(precision)) {
|
11989 |
+
factor = Math.pow(10, precision);
|
11990 |
+
spacing = Math.ceil(spacing * factor) / factor;
|
11991 |
+
}
|
11992 |
+
if (bounds === 'ticks') {
|
11993 |
+
niceMin = Math.floor(rmin / spacing) * spacing;
|
11994 |
+
niceMax = Math.ceil(rmax / spacing) * spacing;
|
11995 |
+
} else {
|
11996 |
+
niceMin = rmin;
|
11997 |
+
niceMax = rmax;
|
11998 |
+
}
|
11999 |
+
if (minDefined && maxDefined && step && almostWhole((max - min) / step, spacing / 1000)) {
|
12000 |
+
numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks));
|
12001 |
+
spacing = (max - min) / numSpaces;
|
12002 |
+
niceMin = min;
|
12003 |
+
niceMax = max;
|
12004 |
+
} else if (countDefined) {
|
12005 |
+
niceMin = minDefined ? min : niceMin;
|
12006 |
+
niceMax = maxDefined ? max : niceMax;
|
12007 |
+
numSpaces = count - 1;
|
12008 |
+
spacing = (niceMax - niceMin) / numSpaces;
|
12009 |
+
} else {
|
12010 |
+
numSpaces = (niceMax - niceMin) / spacing;
|
12011 |
+
if (almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
|
12012 |
+
numSpaces = Math.round(numSpaces);
|
12013 |
+
} else {
|
12014 |
+
numSpaces = Math.ceil(numSpaces);
|
12015 |
+
}
|
12016 |
+
}
|
12017 |
+
const decimalPlaces = Math.max(
|
12018 |
+
_decimalPlaces(spacing),
|
12019 |
+
_decimalPlaces(niceMin)
|
12020 |
+
);
|
12021 |
+
factor = Math.pow(10, isNullOrUndef(precision) ? decimalPlaces : precision);
|
12022 |
+
niceMin = Math.round(niceMin * factor) / factor;
|
12023 |
+
niceMax = Math.round(niceMax * factor) / factor;
|
12024 |
+
let j = 0;
|
12025 |
+
if (minDefined) {
|
12026 |
+
if (includeBounds && niceMin !== min) {
|
12027 |
+
ticks.push({value: min});
|
12028 |
+
if (niceMin < min) {
|
12029 |
+
j++;
|
12030 |
+
}
|
12031 |
+
if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) {
|
12032 |
+
j++;
|
12033 |
+
}
|
12034 |
+
} else if (niceMin < min) {
|
12035 |
+
j++;
|
12036 |
+
}
|
12037 |
+
}
|
12038 |
+
for (; j < numSpaces; ++j) {
|
12039 |
+
ticks.push({value: Math.round((niceMin + j * spacing) * factor) / factor});
|
12040 |
+
}
|
12041 |
+
if (maxDefined && includeBounds && niceMax !== max) {
|
12042 |
+
if (ticks.length && almostEquals(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) {
|
12043 |
+
ticks[ticks.length - 1].value = max;
|
12044 |
+
} else {
|
12045 |
+
ticks.push({value: max});
|
12046 |
+
}
|
12047 |
+
} else if (!maxDefined || niceMax === max) {
|
12048 |
+
ticks.push({value: niceMax});
|
12049 |
+
}
|
12050 |
+
return ticks;
|
12051 |
+
}
|
12052 |
+
function relativeLabelSize(value, minSpacing, {horizontal, minRotation}) {
|
12053 |
+
const rad = toRadians(minRotation);
|
12054 |
+
const ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 0.001;
|
12055 |
+
const length = 0.75 * minSpacing * ('' + value).length;
|
12056 |
+
return Math.min(minSpacing / ratio, length);
|
12057 |
+
}
|
12058 |
+
class LinearScaleBase extends Scale {
|
12059 |
+
constructor(cfg) {
|
12060 |
+
super(cfg);
|
12061 |
+
this.start = undefined;
|
12062 |
+
this.end = undefined;
|
12063 |
+
this._startValue = undefined;
|
12064 |
+
this._endValue = undefined;
|
12065 |
+
this._valueRange = 0;
|
12066 |
+
}
|
12067 |
+
parse(raw, index) {
|
12068 |
+
if (isNullOrUndef(raw)) {
|
12069 |
+
return null;
|
12070 |
+
}
|
12071 |
+
if ((typeof raw === 'number' || raw instanceof Number) && !isFinite(+raw)) {
|
12072 |
+
return null;
|
12073 |
+
}
|
12074 |
+
return +raw;
|
12075 |
+
}
|
12076 |
+
handleTickRangeOptions() {
|
12077 |
+
const {beginAtZero} = this.options;
|
12078 |
+
const {minDefined, maxDefined} = this.getUserBounds();
|
12079 |
+
let {min, max} = this;
|
12080 |
+
const setMin = v => (min = minDefined ? min : v);
|
12081 |
+
const setMax = v => (max = maxDefined ? max : v);
|
12082 |
+
if (beginAtZero) {
|
12083 |
+
const minSign = sign(min);
|
12084 |
+
const maxSign = sign(max);
|
12085 |
+
if (minSign < 0 && maxSign < 0) {
|
12086 |
+
setMax(0);
|
12087 |
+
} else if (minSign > 0 && maxSign > 0) {
|
12088 |
+
setMin(0);
|
12089 |
+
}
|
12090 |
+
}
|
12091 |
+
if (min === max) {
|
12092 |
+
let offset = 1;
|
12093 |
+
if (max >= Number.MAX_SAFE_INTEGER || min <= Number.MIN_SAFE_INTEGER) {
|
12094 |
+
offset = Math.abs(max * 0.05);
|
12095 |
+
}
|
12096 |
+
setMax(max + offset);
|
12097 |
+
if (!beginAtZero) {
|
12098 |
+
setMin(min - offset);
|
12099 |
+
}
|
12100 |
+
}
|
12101 |
+
this.min = min;
|
12102 |
+
this.max = max;
|
12103 |
+
}
|
12104 |
+
getTickLimit() {
|
12105 |
+
const tickOpts = this.options.ticks;
|
12106 |
+
let {maxTicksLimit, stepSize} = tickOpts;
|
12107 |
+
let maxTicks;
|
12108 |
+
if (stepSize) {
|
12109 |
+
maxTicks = Math.ceil(this.max / stepSize) - Math.floor(this.min / stepSize) + 1;
|
12110 |
+
if (maxTicks > 1000) {
|
12111 |
+
console.warn(`scales.${this.id}.ticks.stepSize: ${stepSize} would result generating up to ${maxTicks} ticks. Limiting to 1000.`);
|
12112 |
+
maxTicks = 1000;
|
12113 |
+
}
|
12114 |
+
} else {
|
12115 |
+
maxTicks = this.computeTickLimit();
|
12116 |
+
maxTicksLimit = maxTicksLimit || 11;
|
12117 |
+
}
|
12118 |
+
if (maxTicksLimit) {
|
12119 |
+
maxTicks = Math.min(maxTicksLimit, maxTicks);
|
12120 |
+
}
|
12121 |
+
return maxTicks;
|
12122 |
+
}
|
12123 |
+
computeTickLimit() {
|
12124 |
+
return Number.POSITIVE_INFINITY;
|
12125 |
+
}
|
12126 |
+
buildTicks() {
|
12127 |
+
const opts = this.options;
|
12128 |
+
const tickOpts = opts.ticks;
|
12129 |
+
let maxTicks = this.getTickLimit();
|
12130 |
+
maxTicks = Math.max(2, maxTicks);
|
12131 |
+
const numericGeneratorOptions = {
|
12132 |
+
maxTicks,
|
12133 |
+
bounds: opts.bounds,
|
12134 |
+
min: opts.min,
|
12135 |
+
max: opts.max,
|
12136 |
+
precision: tickOpts.precision,
|
12137 |
+
step: tickOpts.stepSize,
|
12138 |
+
count: tickOpts.count,
|
12139 |
+
maxDigits: this._maxDigits(),
|
12140 |
+
horizontal: this.isHorizontal(),
|
12141 |
+
minRotation: tickOpts.minRotation || 0,
|
12142 |
+
includeBounds: tickOpts.includeBounds !== false
|
12143 |
+
};
|
12144 |
+
const dataRange = this._range || this;
|
12145 |
+
const ticks = generateTicks$1(numericGeneratorOptions, dataRange);
|
12146 |
+
if (opts.bounds === 'ticks') {
|
12147 |
+
_setMinAndMaxByKey(ticks, this, 'value');
|
12148 |
+
}
|
12149 |
+
if (opts.reverse) {
|
12150 |
+
ticks.reverse();
|
12151 |
+
this.start = this.max;
|
12152 |
+
this.end = this.min;
|
12153 |
+
} else {
|
12154 |
+
this.start = this.min;
|
12155 |
+
this.end = this.max;
|
12156 |
+
}
|
12157 |
+
return ticks;
|
12158 |
+
}
|
12159 |
+
configure() {
|
12160 |
+
const ticks = this.ticks;
|
12161 |
+
let start = this.min;
|
12162 |
+
let end = this.max;
|
12163 |
+
super.configure();
|
12164 |
+
if (this.options.offset && ticks.length) {
|
12165 |
+
const offset = (end - start) / Math.max(ticks.length - 1, 1) / 2;
|
12166 |
+
start -= offset;
|
12167 |
+
end += offset;
|
12168 |
+
}
|
12169 |
+
this._startValue = start;
|
12170 |
+
this._endValue = end;
|
12171 |
+
this._valueRange = end - start;
|
12172 |
+
}
|
12173 |
+
getLabelForValue(value) {
|
12174 |
+
return formatNumber(value, this.chart.options.locale, this.options.ticks.format);
|
12175 |
+
}
|
12176 |
+
}
|
12177 |
+
|
12178 |
+
class LinearScale extends LinearScaleBase {
|
12179 |
+
determineDataLimits() {
|
12180 |
+
const {min, max} = this.getMinMax(true);
|
12181 |
+
this.min = isNumberFinite(min) ? min : 0;
|
12182 |
+
this.max = isNumberFinite(max) ? max : 1;
|
12183 |
+
this.handleTickRangeOptions();
|
12184 |
+
}
|
12185 |
+
computeTickLimit() {
|
12186 |
+
const horizontal = this.isHorizontal();
|
12187 |
+
const length = horizontal ? this.width : this.height;
|
12188 |
+
const minRotation = toRadians(this.options.ticks.minRotation);
|
12189 |
+
const ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 0.001;
|
12190 |
+
const tickFont = this._resolveTickFontOptions(0);
|
12191 |
+
return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio));
|
12192 |
+
}
|
12193 |
+
getPixelForValue(value) {
|
12194 |
+
return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange);
|
12195 |
+
}
|
12196 |
+
getValueForPixel(pixel) {
|
12197 |
+
return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange;
|
12198 |
+
}
|
12199 |
+
}
|
12200 |
+
LinearScale.id = 'linear';
|
12201 |
+
LinearScale.defaults = {
|
12202 |
+
ticks: {
|
12203 |
+
callback: Ticks.formatters.numeric
|
12204 |
+
}
|
12205 |
+
};
|
12206 |
+
|
12207 |
+
function isMajor(tickVal) {
|
12208 |
+
const remain = tickVal / (Math.pow(10, Math.floor(log10(tickVal))));
|
12209 |
+
return remain === 1;
|
12210 |
+
}
|
12211 |
+
function generateTicks(generationOptions, dataRange) {
|
12212 |
+
const endExp = Math.floor(log10(dataRange.max));
|
12213 |
+
const endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
|
12214 |
+
const ticks = [];
|
12215 |
+
let tickVal = finiteOrDefault(generationOptions.min, Math.pow(10, Math.floor(log10(dataRange.min))));
|
12216 |
+
let exp = Math.floor(log10(tickVal));
|
12217 |
+
let significand = Math.floor(tickVal / Math.pow(10, exp));
|
12218 |
+
let precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;
|
12219 |
+
do {
|
12220 |
+
ticks.push({value: tickVal, major: isMajor(tickVal)});
|
12221 |
+
++significand;
|
12222 |
+
if (significand === 10) {
|
12223 |
+
significand = 1;
|
12224 |
+
++exp;
|
12225 |
+
precision = exp >= 0 ? 1 : precision;
|
12226 |
+
}
|
12227 |
+
tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision;
|
12228 |
+
} while (exp < endExp || (exp === endExp && significand < endSignificand));
|
12229 |
+
const lastTick = finiteOrDefault(generationOptions.max, tickVal);
|
12230 |
+
ticks.push({value: lastTick, major: isMajor(tickVal)});
|
12231 |
+
return ticks;
|
12232 |
+
}
|
12233 |
+
class LogarithmicScale extends Scale {
|
12234 |
+
constructor(cfg) {
|
12235 |
+
super(cfg);
|
12236 |
+
this.start = undefined;
|
12237 |
+
this.end = undefined;
|
12238 |
+
this._startValue = undefined;
|
12239 |
+
this._valueRange = 0;
|
12240 |
+
}
|
12241 |
+
parse(raw, index) {
|
12242 |
+
const value = LinearScaleBase.prototype.parse.apply(this, [raw, index]);
|
12243 |
+
if (value === 0) {
|
12244 |
+
this._zero = true;
|
12245 |
+
return undefined;
|
12246 |
+
}
|
12247 |
+
return isNumberFinite(value) && value > 0 ? value : null;
|
12248 |
+
}
|
12249 |
+
determineDataLimits() {
|
12250 |
+
const {min, max} = this.getMinMax(true);
|
12251 |
+
this.min = isNumberFinite(min) ? Math.max(0, min) : null;
|
12252 |
+
this.max = isNumberFinite(max) ? Math.max(0, max) : null;
|
12253 |
+
if (this.options.beginAtZero) {
|
12254 |
+
this._zero = true;
|
12255 |
+
}
|
12256 |
+
this.handleTickRangeOptions();
|
12257 |
+
}
|
12258 |
+
handleTickRangeOptions() {
|
12259 |
+
const {minDefined, maxDefined} = this.getUserBounds();
|
12260 |
+
let min = this.min;
|
12261 |
+
let max = this.max;
|
12262 |
+
const setMin = v => (min = minDefined ? min : v);
|
12263 |
+
const setMax = v => (max = maxDefined ? max : v);
|
12264 |
+
const exp = (v, m) => Math.pow(10, Math.floor(log10(v)) + m);
|
12265 |
+
if (min === max) {
|
12266 |
+
if (min <= 0) {
|
12267 |
+
setMin(1);
|
12268 |
+
setMax(10);
|
12269 |
+
} else {
|
12270 |
+
setMin(exp(min, -1));
|
12271 |
+
setMax(exp(max, +1));
|
12272 |
+
}
|
12273 |
+
}
|
12274 |
+
if (min <= 0) {
|
12275 |
+
setMin(exp(max, -1));
|
12276 |
+
}
|
12277 |
+
if (max <= 0) {
|
12278 |
+
setMax(exp(min, +1));
|
12279 |
+
}
|
12280 |
+
if (this._zero && this.min !== this._suggestedMin && min === exp(this.min, 0)) {
|
12281 |
+
setMin(exp(min, -1));
|
12282 |
+
}
|
12283 |
+
this.min = min;
|
12284 |
+
this.max = max;
|
12285 |
+
}
|
12286 |
+
buildTicks() {
|
12287 |
+
const opts = this.options;
|
12288 |
+
const generationOptions = {
|
12289 |
+
min: this._userMin,
|
12290 |
+
max: this._userMax
|
12291 |
+
};
|
12292 |
+
const ticks = generateTicks(generationOptions, this);
|
12293 |
+
if (opts.bounds === 'ticks') {
|
12294 |
+
_setMinAndMaxByKey(ticks, this, 'value');
|
12295 |
+
}
|
12296 |
+
if (opts.reverse) {
|
12297 |
+
ticks.reverse();
|
12298 |
+
this.start = this.max;
|
12299 |
+
this.end = this.min;
|
12300 |
+
} else {
|
12301 |
+
this.start = this.min;
|
12302 |
+
this.end = this.max;
|
12303 |
+
}
|
12304 |
+
return ticks;
|
12305 |
+
}
|
12306 |
+
getLabelForValue(value) {
|
12307 |
+
return value === undefined
|
12308 |
+
? '0'
|
12309 |
+
: formatNumber(value, this.chart.options.locale, this.options.ticks.format);
|
12310 |
+
}
|
12311 |
+
configure() {
|
12312 |
+
const start = this.min;
|
12313 |
+
super.configure();
|
12314 |
+
this._startValue = log10(start);
|
12315 |
+
this._valueRange = log10(this.max) - log10(start);
|
12316 |
+
}
|
12317 |
+
getPixelForValue(value) {
|
12318 |
+
if (value === undefined || value === 0) {
|
12319 |
+
value = this.min;
|
12320 |
+
}
|
12321 |
+
if (value === null || isNaN(value)) {
|
12322 |
+
return NaN;
|
12323 |
+
}
|
12324 |
+
return this.getPixelForDecimal(value === this.min
|
12325 |
+
? 0
|
12326 |
+
: (log10(value) - this._startValue) / this._valueRange);
|
12327 |
+
}
|
12328 |
+
getValueForPixel(pixel) {
|
12329 |
+
const decimal = this.getDecimalForPixel(pixel);
|
12330 |
+
return Math.pow(10, this._startValue + decimal * this._valueRange);
|
12331 |
+
}
|
12332 |
+
}
|
12333 |
+
LogarithmicScale.id = 'logarithmic';
|
12334 |
+
LogarithmicScale.defaults = {
|
12335 |
+
ticks: {
|
12336 |
+
callback: Ticks.formatters.logarithmic,
|
12337 |
+
major: {
|
12338 |
+
enabled: true
|
12339 |
+
}
|
12340 |
+
}
|
12341 |
+
};
|
12342 |
+
|
12343 |
+
function getTickBackdropHeight(opts) {
|
12344 |
+
const tickOpts = opts.ticks;
|
12345 |
+
if (tickOpts.display && opts.display) {
|
12346 |
+
const padding = toPadding(tickOpts.backdropPadding);
|
12347 |
+
return valueOrDefault(tickOpts.font && tickOpts.font.size, defaults.font.size) + padding.height;
|
12348 |
+
}
|
12349 |
+
return 0;
|
12350 |
+
}
|
12351 |
+
function measureLabelSize(ctx, font, label) {
|
12352 |
+
label = isArray(label) ? label : [label];
|
12353 |
+
return {
|
12354 |
+
w: _longestText(ctx, font.string, label),
|
12355 |
+
h: label.length * font.lineHeight
|
12356 |
+
};
|
12357 |
+
}
|
12358 |
+
function determineLimits(angle, pos, size, min, max) {
|
12359 |
+
if (angle === min || angle === max) {
|
12360 |
+
return {
|
12361 |
+
start: pos - (size / 2),
|
12362 |
+
end: pos + (size / 2)
|
12363 |
+
};
|
12364 |
+
} else if (angle < min || angle > max) {
|
12365 |
+
return {
|
12366 |
+
start: pos - size,
|
12367 |
+
end: pos
|
12368 |
+
};
|
12369 |
+
}
|
12370 |
+
return {
|
12371 |
+
start: pos,
|
12372 |
+
end: pos + size
|
12373 |
+
};
|
12374 |
+
}
|
12375 |
+
function fitWithPointLabels(scale) {
|
12376 |
+
const orig = {
|
12377 |
+
l: scale.left + scale._padding.left,
|
12378 |
+
r: scale.right - scale._padding.right,
|
12379 |
+
t: scale.top + scale._padding.top,
|
12380 |
+
b: scale.bottom - scale._padding.bottom
|
12381 |
+
};
|
12382 |
+
const limits = Object.assign({}, orig);
|
12383 |
+
const labelSizes = [];
|
12384 |
+
const padding = [];
|
12385 |
+
const valueCount = scale._pointLabels.length;
|
12386 |
+
const pointLabelOpts = scale.options.pointLabels;
|
12387 |
+
const additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0;
|
12388 |
+
for (let i = 0; i < valueCount; i++) {
|
12389 |
+
const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i));
|
12390 |
+
padding[i] = opts.padding;
|
12391 |
+
const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle);
|
12392 |
+
const plFont = toFont(opts.font);
|
12393 |
+
const textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]);
|
12394 |
+
labelSizes[i] = textSize;
|
12395 |
+
const angleRadians = _normalizeAngle(scale.getIndexAngle(i) + additionalAngle);
|
12396 |
+
const angle = Math.round(toDegrees(angleRadians));
|
12397 |
+
const hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
|
12398 |
+
const vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
|
12399 |
+
updateLimits(limits, orig, angleRadians, hLimits, vLimits);
|
12400 |
+
}
|
12401 |
+
scale.setCenterPoint(
|
12402 |
+
orig.l - limits.l,
|
12403 |
+
limits.r - orig.r,
|
12404 |
+
orig.t - limits.t,
|
12405 |
+
limits.b - orig.b
|
12406 |
+
);
|
12407 |
+
scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding);
|
12408 |
+
}
|
12409 |
+
function updateLimits(limits, orig, angle, hLimits, vLimits) {
|
12410 |
+
const sin = Math.abs(Math.sin(angle));
|
12411 |
+
const cos = Math.abs(Math.cos(angle));
|
12412 |
+
let x = 0;
|
12413 |
+
let y = 0;
|
12414 |
+
if (hLimits.start < orig.l) {
|
12415 |
+
x = (orig.l - hLimits.start) / sin;
|
12416 |
+
limits.l = Math.min(limits.l, orig.l - x);
|
12417 |
+
} else if (hLimits.end > orig.r) {
|
12418 |
+
x = (hLimits.end - orig.r) / sin;
|
12419 |
+
limits.r = Math.max(limits.r, orig.r + x);
|
12420 |
+
}
|
12421 |
+
if (vLimits.start < orig.t) {
|
12422 |
+
y = (orig.t - vLimits.start) / cos;
|
12423 |
+
limits.t = Math.min(limits.t, orig.t - y);
|
12424 |
+
} else if (vLimits.end > orig.b) {
|
12425 |
+
y = (vLimits.end - orig.b) / cos;
|
12426 |
+
limits.b = Math.max(limits.b, orig.b + y);
|
12427 |
+
}
|
12428 |
+
}
|
12429 |
+
function buildPointLabelItems(scale, labelSizes, padding) {
|
12430 |
+
const items = [];
|
12431 |
+
const valueCount = scale._pointLabels.length;
|
12432 |
+
const opts = scale.options;
|
12433 |
+
const extra = getTickBackdropHeight(opts) / 2;
|
12434 |
+
const outerDistance = scale.drawingArea;
|
12435 |
+
const additionalAngle = opts.pointLabels.centerPointLabels ? PI / valueCount : 0;
|
12436 |
+
for (let i = 0; i < valueCount; i++) {
|
12437 |
+
const pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i], additionalAngle);
|
12438 |
+
const angle = Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle + HALF_PI)));
|
12439 |
+
const size = labelSizes[i];
|
12440 |
+
const y = yForAngle(pointLabelPosition.y, size.h, angle);
|
12441 |
+
const textAlign = getTextAlignForAngle(angle);
|
12442 |
+
const left = leftForTextAlign(pointLabelPosition.x, size.w, textAlign);
|
12443 |
+
items.push({
|
12444 |
+
x: pointLabelPosition.x,
|
12445 |
+
y,
|
12446 |
+
textAlign,
|
12447 |
+
left,
|
12448 |
+
top: y,
|
12449 |
+
right: left + size.w,
|
12450 |
+
bottom: y + size.h
|
12451 |
+
});
|
12452 |
+
}
|
12453 |
+
return items;
|
12454 |
+
}
|
12455 |
+
function getTextAlignForAngle(angle) {
|
12456 |
+
if (angle === 0 || angle === 180) {
|
12457 |
+
return 'center';
|
12458 |
+
} else if (angle < 180) {
|
12459 |
+
return 'left';
|
12460 |
+
}
|
12461 |
+
return 'right';
|
12462 |
+
}
|
12463 |
+
function leftForTextAlign(x, w, align) {
|
12464 |
+
if (align === 'right') {
|
12465 |
+
x -= w;
|
12466 |
+
} else if (align === 'center') {
|
12467 |
+
x -= (w / 2);
|
12468 |
+
}
|
12469 |
+
return x;
|
12470 |
+
}
|
12471 |
+
function yForAngle(y, h, angle) {
|
12472 |
+
if (angle === 90 || angle === 270) {
|
12473 |
+
y -= (h / 2);
|
12474 |
+
} else if (angle > 270 || angle < 90) {
|
12475 |
+
y -= h;
|
12476 |
+
}
|
12477 |
+
return y;
|
12478 |
+
}
|
12479 |
+
function drawPointLabels(scale, labelCount) {
|
12480 |
+
const {ctx, options: {pointLabels}} = scale;
|
12481 |
+
for (let i = labelCount - 1; i >= 0; i--) {
|
12482 |
+
const optsAtIndex = pointLabels.setContext(scale.getPointLabelContext(i));
|
12483 |
+
const plFont = toFont(optsAtIndex.font);
|
12484 |
+
const {x, y, textAlign, left, top, right, bottom} = scale._pointLabelItems[i];
|
12485 |
+
const {backdropColor} = optsAtIndex;
|
12486 |
+
if (!isNullOrUndef(backdropColor)) {
|
12487 |
+
const padding = toPadding(optsAtIndex.backdropPadding);
|
12488 |
+
ctx.fillStyle = backdropColor;
|
12489 |
+
ctx.fillRect(left - padding.left, top - padding.top, right - left + padding.width, bottom - top + padding.height);
|
12490 |
+
}
|
12491 |
+
renderText(
|
12492 |
+
ctx,
|
12493 |
+
scale._pointLabels[i],
|
12494 |
+
x,
|
12495 |
+
y + (plFont.lineHeight / 2),
|
12496 |
+
plFont,
|
12497 |
+
{
|
12498 |
+
color: optsAtIndex.color,
|
12499 |
+
textAlign: textAlign,
|
12500 |
+
textBaseline: 'middle'
|
12501 |
+
}
|
12502 |
+
);
|
12503 |
+
}
|
12504 |
+
}
|
12505 |
+
function pathRadiusLine(scale, radius, circular, labelCount) {
|
12506 |
+
const {ctx} = scale;
|
12507 |
+
if (circular) {
|
12508 |
+
ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU);
|
12509 |
+
} else {
|
12510 |
+
let pointPosition = scale.getPointPosition(0, radius);
|
12511 |
+
ctx.moveTo(pointPosition.x, pointPosition.y);
|
12512 |
+
for (let i = 1; i < labelCount; i++) {
|
12513 |
+
pointPosition = scale.getPointPosition(i, radius);
|
12514 |
+
ctx.lineTo(pointPosition.x, pointPosition.y);
|
12515 |
+
}
|
12516 |
+
}
|
12517 |
+
}
|
12518 |
+
function drawRadiusLine(scale, gridLineOpts, radius, labelCount) {
|
12519 |
+
const ctx = scale.ctx;
|
12520 |
+
const circular = gridLineOpts.circular;
|
12521 |
+
const {color, lineWidth} = gridLineOpts;
|
12522 |
+
if ((!circular && !labelCount) || !color || !lineWidth || radius < 0) {
|
12523 |
+
return;
|
12524 |
+
}
|
12525 |
+
ctx.save();
|
12526 |
+
ctx.strokeStyle = color;
|
12527 |
+
ctx.lineWidth = lineWidth;
|
12528 |
+
ctx.setLineDash(gridLineOpts.borderDash);
|
12529 |
+
ctx.lineDashOffset = gridLineOpts.borderDashOffset;
|
12530 |
+
ctx.beginPath();
|
12531 |
+
pathRadiusLine(scale, radius, circular, labelCount);
|
12532 |
+
ctx.closePath();
|
12533 |
+
ctx.stroke();
|
12534 |
+
ctx.restore();
|
12535 |
+
}
|
12536 |
+
function createPointLabelContext(parent, index, label) {
|
12537 |
+
return createContext(parent, {
|
12538 |
+
label,
|
12539 |
+
index,
|
12540 |
+
type: 'pointLabel'
|
12541 |
+
});
|
12542 |
+
}
|
12543 |
+
class RadialLinearScale extends LinearScaleBase {
|
12544 |
+
constructor(cfg) {
|
12545 |
+
super(cfg);
|
12546 |
+
this.xCenter = undefined;
|
12547 |
+
this.yCenter = undefined;
|
12548 |
+
this.drawingArea = undefined;
|
12549 |
+
this._pointLabels = [];
|
12550 |
+
this._pointLabelItems = [];
|
12551 |
+
}
|
12552 |
+
setDimensions() {
|
12553 |
+
const padding = this._padding = toPadding(getTickBackdropHeight(this.options) / 2);
|
12554 |
+
const w = this.width = this.maxWidth - padding.width;
|
12555 |
+
const h = this.height = this.maxHeight - padding.height;
|
12556 |
+
this.xCenter = Math.floor(this.left + w / 2 + padding.left);
|
12557 |
+
this.yCenter = Math.floor(this.top + h / 2 + padding.top);
|
12558 |
+
this.drawingArea = Math.floor(Math.min(w, h) / 2);
|
12559 |
+
}
|
12560 |
+
determineDataLimits() {
|
12561 |
+
const {min, max} = this.getMinMax(false);
|
12562 |
+
this.min = isNumberFinite(min) && !isNaN(min) ? min : 0;
|
12563 |
+
this.max = isNumberFinite(max) && !isNaN(max) ? max : 0;
|
12564 |
+
this.handleTickRangeOptions();
|
12565 |
+
}
|
12566 |
+
computeTickLimit() {
|
12567 |
+
return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options));
|
12568 |
+
}
|
12569 |
+
generateTickLabels(ticks) {
|
12570 |
+
LinearScaleBase.prototype.generateTickLabels.call(this, ticks);
|
12571 |
+
this._pointLabels = this.getLabels()
|
12572 |
+
.map((value, index) => {
|
12573 |
+
const label = callback(this.options.pointLabels.callback, [value, index], this);
|
12574 |
+
return label || label === 0 ? label : '';
|
12575 |
+
})
|
12576 |
+
.filter((v, i) => this.chart.getDataVisibility(i));
|
12577 |
+
}
|
12578 |
+
fit() {
|
12579 |
+
const opts = this.options;
|
12580 |
+
if (opts.display && opts.pointLabels.display) {
|
12581 |
+
fitWithPointLabels(this);
|
12582 |
+
} else {
|
12583 |
+
this.setCenterPoint(0, 0, 0, 0);
|
12584 |
+
}
|
12585 |
+
}
|
12586 |
+
setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) {
|
12587 |
+
this.xCenter += Math.floor((leftMovement - rightMovement) / 2);
|
12588 |
+
this.yCenter += Math.floor((topMovement - bottomMovement) / 2);
|
12589 |
+
this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement));
|
12590 |
+
}
|
12591 |
+
getIndexAngle(index) {
|
12592 |
+
const angleMultiplier = TAU / (this._pointLabels.length || 1);
|
12593 |
+
const startAngle = this.options.startAngle || 0;
|
12594 |
+
return _normalizeAngle(index * angleMultiplier + toRadians(startAngle));
|
12595 |
+
}
|
12596 |
+
getDistanceFromCenterForValue(value) {
|
12597 |
+
if (isNullOrUndef(value)) {
|
12598 |
+
return NaN;
|
12599 |
+
}
|
12600 |
+
const scalingFactor = this.drawingArea / (this.max - this.min);
|
12601 |
+
if (this.options.reverse) {
|
12602 |
+
return (this.max - value) * scalingFactor;
|
12603 |
+
}
|
12604 |
+
return (value - this.min) * scalingFactor;
|
12605 |
+
}
|
12606 |
+
getValueForDistanceFromCenter(distance) {
|
12607 |
+
if (isNullOrUndef(distance)) {
|
12608 |
+
return NaN;
|
12609 |
+
}
|
12610 |
+
const scaledDistance = distance / (this.drawingArea / (this.max - this.min));
|
12611 |
+
return this.options.reverse ? this.max - scaledDistance : this.min + scaledDistance;
|
12612 |
+
}
|
12613 |
+
getPointLabelContext(index) {
|
12614 |
+
const pointLabels = this._pointLabels || [];
|
12615 |
+
if (index >= 0 && index < pointLabels.length) {
|
12616 |
+
const pointLabel = pointLabels[index];
|
12617 |
+
return createPointLabelContext(this.getContext(), index, pointLabel);
|
12618 |
+
}
|
12619 |
+
}
|
12620 |
+
getPointPosition(index, distanceFromCenter, additionalAngle = 0) {
|
12621 |
+
const angle = this.getIndexAngle(index) - HALF_PI + additionalAngle;
|
12622 |
+
return {
|
12623 |
+
x: Math.cos(angle) * distanceFromCenter + this.xCenter,
|
12624 |
+
y: Math.sin(angle) * distanceFromCenter + this.yCenter,
|
12625 |
+
angle
|
12626 |
+
};
|
12627 |
+
}
|
12628 |
+
getPointPositionForValue(index, value) {
|
12629 |
+
return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
|
12630 |
+
}
|
12631 |
+
getBasePosition(index) {
|
12632 |
+
return this.getPointPositionForValue(index || 0, this.getBaseValue());
|
12633 |
+
}
|
12634 |
+
getPointLabelPosition(index) {
|
12635 |
+
const {left, top, right, bottom} = this._pointLabelItems[index];
|
12636 |
+
return {
|
12637 |
+
left,
|
12638 |
+
top,
|
12639 |
+
right,
|
12640 |
+
bottom,
|
12641 |
+
};
|
12642 |
+
}
|
12643 |
+
drawBackground() {
|
12644 |
+
const {backgroundColor, grid: {circular}} = this.options;
|
12645 |
+
if (backgroundColor) {
|
12646 |
+
const ctx = this.ctx;
|
12647 |
+
ctx.save();
|
12648 |
+
ctx.beginPath();
|
12649 |
+
pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length);
|
12650 |
+
ctx.closePath();
|
12651 |
+
ctx.fillStyle = backgroundColor;
|
12652 |
+
ctx.fill();
|
12653 |
+
ctx.restore();
|
12654 |
+
}
|
12655 |
+
}
|
12656 |
+
drawGrid() {
|
12657 |
+
const ctx = this.ctx;
|
12658 |
+
const opts = this.options;
|
12659 |
+
const {angleLines, grid} = opts;
|
12660 |
+
const labelCount = this._pointLabels.length;
|
12661 |
+
let i, offset, position;
|
12662 |
+
if (opts.pointLabels.display) {
|
12663 |
+
drawPointLabels(this, labelCount);
|
12664 |
+
}
|
12665 |
+
if (grid.display) {
|
12666 |
+
this.ticks.forEach((tick, index) => {
|
12667 |
+
if (index !== 0) {
|
12668 |
+
offset = this.getDistanceFromCenterForValue(tick.value);
|
12669 |
+
const optsAtIndex = grid.setContext(this.getContext(index - 1));
|
12670 |
+
drawRadiusLine(this, optsAtIndex, offset, labelCount);
|
12671 |
+
}
|
12672 |
+
});
|
12673 |
+
}
|
12674 |
+
if (angleLines.display) {
|
12675 |
+
ctx.save();
|
12676 |
+
for (i = labelCount - 1; i >= 0; i--) {
|
12677 |
+
const optsAtIndex = angleLines.setContext(this.getPointLabelContext(i));
|
12678 |
+
const {color, lineWidth} = optsAtIndex;
|
12679 |
+
if (!lineWidth || !color) {
|
12680 |
+
continue;
|
12681 |
+
}
|
12682 |
+
ctx.lineWidth = lineWidth;
|
12683 |
+
ctx.strokeStyle = color;
|
12684 |
+
ctx.setLineDash(optsAtIndex.borderDash);
|
12685 |
+
ctx.lineDashOffset = optsAtIndex.borderDashOffset;
|
12686 |
+
offset = this.getDistanceFromCenterForValue(opts.ticks.reverse ? this.min : this.max);
|
12687 |
+
position = this.getPointPosition(i, offset);
|
12688 |
+
ctx.beginPath();
|
12689 |
+
ctx.moveTo(this.xCenter, this.yCenter);
|
12690 |
+
ctx.lineTo(position.x, position.y);
|
12691 |
+
ctx.stroke();
|
12692 |
+
}
|
12693 |
+
ctx.restore();
|
12694 |
+
}
|
12695 |
+
}
|
12696 |
+
drawBorder() {}
|
12697 |
+
drawLabels() {
|
12698 |
+
const ctx = this.ctx;
|
12699 |
+
const opts = this.options;
|
12700 |
+
const tickOpts = opts.ticks;
|
12701 |
+
if (!tickOpts.display) {
|
12702 |
+
return;
|
12703 |
+
}
|
12704 |
+
const startAngle = this.getIndexAngle(0);
|
12705 |
+
let offset, width;
|
12706 |
+
ctx.save();
|
12707 |
+
ctx.translate(this.xCenter, this.yCenter);
|
12708 |
+
ctx.rotate(startAngle);
|
12709 |
+
ctx.textAlign = 'center';
|
12710 |
+
ctx.textBaseline = 'middle';
|
12711 |
+
this.ticks.forEach((tick, index) => {
|
12712 |
+
if (index === 0 && !opts.reverse) {
|
12713 |
+
return;
|
12714 |
+
}
|
12715 |
+
const optsAtIndex = tickOpts.setContext(this.getContext(index));
|
12716 |
+
const tickFont = toFont(optsAtIndex.font);
|
12717 |
+
offset = this.getDistanceFromCenterForValue(this.ticks[index].value);
|
12718 |
+
if (optsAtIndex.showLabelBackdrop) {
|
12719 |
+
ctx.font = tickFont.string;
|
12720 |
+
width = ctx.measureText(tick.label).width;
|
12721 |
+
ctx.fillStyle = optsAtIndex.backdropColor;
|
12722 |
+
const padding = toPadding(optsAtIndex.backdropPadding);
|
12723 |
+
ctx.fillRect(
|
12724 |
+
-width / 2 - padding.left,
|
12725 |
+
-offset - tickFont.size / 2 - padding.top,
|
12726 |
+
width + padding.width,
|
12727 |
+
tickFont.size + padding.height
|
12728 |
+
);
|
12729 |
+
}
|
12730 |
+
renderText(ctx, tick.label, 0, -offset, tickFont, {
|
12731 |
+
color: optsAtIndex.color,
|
12732 |
+
});
|
12733 |
+
});
|
12734 |
+
ctx.restore();
|
12735 |
+
}
|
12736 |
+
drawTitle() {}
|
12737 |
+
}
|
12738 |
+
RadialLinearScale.id = 'radialLinear';
|
12739 |
+
RadialLinearScale.defaults = {
|
12740 |
+
display: true,
|
12741 |
+
animate: true,
|
12742 |
+
position: 'chartArea',
|
12743 |
+
angleLines: {
|
12744 |
+
display: true,
|
12745 |
+
lineWidth: 1,
|
12746 |
+
borderDash: [],
|
12747 |
+
borderDashOffset: 0.0
|
12748 |
+
},
|
12749 |
+
grid: {
|
12750 |
+
circular: false
|
12751 |
+
},
|
12752 |
+
startAngle: 0,
|
12753 |
+
ticks: {
|
12754 |
+
showLabelBackdrop: true,
|
12755 |
+
callback: Ticks.formatters.numeric
|
12756 |
+
},
|
12757 |
+
pointLabels: {
|
12758 |
+
backdropColor: undefined,
|
12759 |
+
backdropPadding: 2,
|
12760 |
+
display: true,
|
12761 |
+
font: {
|
12762 |
+
size: 10
|
12763 |
+
},
|
12764 |
+
callback(label) {
|
12765 |
+
return label;
|
12766 |
+
},
|
12767 |
+
padding: 5,
|
12768 |
+
centerPointLabels: false
|
12769 |
+
}
|
12770 |
+
};
|
12771 |
+
RadialLinearScale.defaultRoutes = {
|
12772 |
+
'angleLines.color': 'borderColor',
|
12773 |
+
'pointLabels.color': 'color',
|
12774 |
+
'ticks.color': 'color'
|
12775 |
+
};
|
12776 |
+
RadialLinearScale.descriptors = {
|
12777 |
+
angleLines: {
|
12778 |
+
_fallback: 'grid'
|
12779 |
+
}
|
12780 |
+
};
|
12781 |
+
|
12782 |
+
const INTERVALS = {
|
12783 |
+
millisecond: {common: true, size: 1, steps: 1000},
|
12784 |
+
second: {common: true, size: 1000, steps: 60},
|
12785 |
+
minute: {common: true, size: 60000, steps: 60},
|
12786 |
+
hour: {common: true, size: 3600000, steps: 24},
|
12787 |
+
day: {common: true, size: 86400000, steps: 30},
|
12788 |
+
week: {common: false, size: 604800000, steps: 4},
|
12789 |
+
month: {common: true, size: 2.628e9, steps: 12},
|
12790 |
+
quarter: {common: false, size: 7.884e9, steps: 4},
|
12791 |
+
year: {common: true, size: 3.154e10}
|
12792 |
+
};
|
12793 |
+
const UNITS = (Object.keys(INTERVALS));
|
12794 |
+
function sorter(a, b) {
|
12795 |
+
return a - b;
|
12796 |
+
}
|
12797 |
+
function parse(scale, input) {
|
12798 |
+
if (isNullOrUndef(input)) {
|
12799 |
+
return null;
|
12800 |
+
}
|
12801 |
+
const adapter = scale._adapter;
|
12802 |
+
const {parser, round, isoWeekday} = scale._parseOpts;
|
12803 |
+
let value = input;
|
12804 |
+
if (typeof parser === 'function') {
|
12805 |
+
value = parser(value);
|
12806 |
+
}
|
12807 |
+
if (!isNumberFinite(value)) {
|
12808 |
+
value = typeof parser === 'string'
|
12809 |
+
? adapter.parse(value, parser)
|
12810 |
+
: adapter.parse(value);
|
12811 |
+
}
|
12812 |
+
if (value === null) {
|
12813 |
+
return null;
|
12814 |
+
}
|
12815 |
+
if (round) {
|
12816 |
+
value = round === 'week' && (isNumber(isoWeekday) || isoWeekday === true)
|
12817 |
+
? adapter.startOf(value, 'isoWeek', isoWeekday)
|
12818 |
+
: adapter.startOf(value, round);
|
12819 |
+
}
|
12820 |
+
return +value;
|
12821 |
+
}
|
12822 |
+
function determineUnitForAutoTicks(minUnit, min, max, capacity) {
|
12823 |
+
const ilen = UNITS.length;
|
12824 |
+
for (let i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {
|
12825 |
+
const interval = INTERVALS[UNITS[i]];
|
12826 |
+
const factor = interval.steps ? interval.steps : Number.MAX_SAFE_INTEGER;
|
12827 |
+
if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {
|
12828 |
+
return UNITS[i];
|
12829 |
+
}
|
12830 |
+
}
|
12831 |
+
return UNITS[ilen - 1];
|
12832 |
+
}
|
12833 |
+
function determineUnitForFormatting(scale, numTicks, minUnit, min, max) {
|
12834 |
+
for (let i = UNITS.length - 1; i >= UNITS.indexOf(minUnit); i--) {
|
12835 |
+
const unit = UNITS[i];
|
12836 |
+
if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) {
|
12837 |
+
return unit;
|
12838 |
+
}
|
12839 |
+
}
|
12840 |
+
return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];
|
12841 |
+
}
|
12842 |
+
function determineMajorUnit(unit) {
|
12843 |
+
for (let i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) {
|
12844 |
+
if (INTERVALS[UNITS[i]].common) {
|
12845 |
+
return UNITS[i];
|
12846 |
+
}
|
12847 |
+
}
|
12848 |
+
}
|
12849 |
+
function addTick(ticks, time, timestamps) {
|
12850 |
+
if (!timestamps) {
|
12851 |
+
ticks[time] = true;
|
12852 |
+
} else if (timestamps.length) {
|
12853 |
+
const {lo, hi} = _lookup(timestamps, time);
|
12854 |
+
const timestamp = timestamps[lo] >= time ? timestamps[lo] : timestamps[hi];
|
12855 |
+
ticks[timestamp] = true;
|
12856 |
+
}
|
12857 |
+
}
|
12858 |
+
function setMajorTicks(scale, ticks, map, majorUnit) {
|
12859 |
+
const adapter = scale._adapter;
|
12860 |
+
const first = +adapter.startOf(ticks[0].value, majorUnit);
|
12861 |
+
const last = ticks[ticks.length - 1].value;
|
12862 |
+
let major, index;
|
12863 |
+
for (major = first; major <= last; major = +adapter.add(major, 1, majorUnit)) {
|
12864 |
+
index = map[major];
|
12865 |
+
if (index >= 0) {
|
12866 |
+
ticks[index].major = true;
|
12867 |
+
}
|
12868 |
+
}
|
12869 |
+
return ticks;
|
12870 |
+
}
|
12871 |
+
function ticksFromTimestamps(scale, values, majorUnit) {
|
12872 |
+
const ticks = [];
|
12873 |
+
const map = {};
|
12874 |
+
const ilen = values.length;
|
12875 |
+
let i, value;
|
12876 |
+
for (i = 0; i < ilen; ++i) {
|
12877 |
+
value = values[i];
|
12878 |
+
map[value] = i;
|
12879 |
+
ticks.push({
|
12880 |
+
value,
|
12881 |
+
major: false
|
12882 |
+
});
|
12883 |
+
}
|
12884 |
+
return (ilen === 0 || !majorUnit) ? ticks : setMajorTicks(scale, ticks, map, majorUnit);
|
12885 |
+
}
|
12886 |
+
class TimeScale extends Scale {
|
12887 |
+
constructor(props) {
|
12888 |
+
super(props);
|
12889 |
+
this._cache = {
|
12890 |
+
data: [],
|
12891 |
+
labels: [],
|
12892 |
+
all: []
|
12893 |
+
};
|
12894 |
+
this._unit = 'day';
|
12895 |
+
this._majorUnit = undefined;
|
12896 |
+
this._offsets = {};
|
12897 |
+
this._normalized = false;
|
12898 |
+
this._parseOpts = undefined;
|
12899 |
+
}
|
12900 |
+
init(scaleOpts, opts) {
|
12901 |
+
const time = scaleOpts.time || (scaleOpts.time = {});
|
12902 |
+
const adapter = this._adapter = new _adapters._date(scaleOpts.adapters.date);
|
12903 |
+
mergeIf(time.displayFormats, adapter.formats());
|
12904 |
+
this._parseOpts = {
|
12905 |
+
parser: time.parser,
|
12906 |
+
round: time.round,
|
12907 |
+
isoWeekday: time.isoWeekday
|
12908 |
+
};
|
12909 |
+
super.init(scaleOpts);
|
12910 |
+
this._normalized = opts.normalized;
|
12911 |
+
}
|
12912 |
+
parse(raw, index) {
|
12913 |
+
if (raw === undefined) {
|
12914 |
+
return null;
|
12915 |
+
}
|
12916 |
+
return parse(this, raw);
|
12917 |
+
}
|
12918 |
+
beforeLayout() {
|
12919 |
+
super.beforeLayout();
|
12920 |
+
this._cache = {
|
12921 |
+
data: [],
|
12922 |
+
labels: [],
|
12923 |
+
all: []
|
12924 |
+
};
|
12925 |
+
}
|
12926 |
+
determineDataLimits() {
|
12927 |
+
const options = this.options;
|
12928 |
+
const adapter = this._adapter;
|
12929 |
+
const unit = options.time.unit || 'day';
|
12930 |
+
let {min, max, minDefined, maxDefined} = this.getUserBounds();
|
12931 |
+
function _applyBounds(bounds) {
|
12932 |
+
if (!minDefined && !isNaN(bounds.min)) {
|
12933 |
+
min = Math.min(min, bounds.min);
|
12934 |
+
}
|
12935 |
+
if (!maxDefined && !isNaN(bounds.max)) {
|
12936 |
+
max = Math.max(max, bounds.max);
|
12937 |
+
}
|
12938 |
+
}
|
12939 |
+
if (!minDefined || !maxDefined) {
|
12940 |
+
_applyBounds(this._getLabelBounds());
|
12941 |
+
if (options.bounds !== 'ticks' || options.ticks.source !== 'labels') {
|
12942 |
+
_applyBounds(this.getMinMax(false));
|
12943 |
+
}
|
12944 |
+
}
|
12945 |
+
min = isNumberFinite(min) && !isNaN(min) ? min : +adapter.startOf(Date.now(), unit);
|
12946 |
+
max = isNumberFinite(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit) + 1;
|
12947 |
+
this.min = Math.min(min, max - 1);
|
12948 |
+
this.max = Math.max(min + 1, max);
|
12949 |
+
}
|
12950 |
+
_getLabelBounds() {
|
12951 |
+
const arr = this.getLabelTimestamps();
|
12952 |
+
let min = Number.POSITIVE_INFINITY;
|
12953 |
+
let max = Number.NEGATIVE_INFINITY;
|
12954 |
+
if (arr.length) {
|
12955 |
+
min = arr[0];
|
12956 |
+
max = arr[arr.length - 1];
|
12957 |
+
}
|
12958 |
+
return {min, max};
|
12959 |
+
}
|
12960 |
+
buildTicks() {
|
12961 |
+
const options = this.options;
|
12962 |
+
const timeOpts = options.time;
|
12963 |
+
const tickOpts = options.ticks;
|
12964 |
+
const timestamps = tickOpts.source === 'labels' ? this.getLabelTimestamps() : this._generate();
|
12965 |
+
if (options.bounds === 'ticks' && timestamps.length) {
|
12966 |
+
this.min = this._userMin || timestamps[0];
|
12967 |
+
this.max = this._userMax || timestamps[timestamps.length - 1];
|
12968 |
+
}
|
12969 |
+
const min = this.min;
|
12970 |
+
const max = this.max;
|
12971 |
+
const ticks = _filterBetween(timestamps, min, max);
|
12972 |
+
this._unit = timeOpts.unit || (tickOpts.autoSkip
|
12973 |
+
? determineUnitForAutoTicks(timeOpts.minUnit, this.min, this.max, this._getLabelCapacity(min))
|
12974 |
+
: determineUnitForFormatting(this, ticks.length, timeOpts.minUnit, this.min, this.max));
|
12975 |
+
this._majorUnit = !tickOpts.major.enabled || this._unit === 'year' ? undefined
|
12976 |
+
: determineMajorUnit(this._unit);
|
12977 |
+
this.initOffsets(timestamps);
|
12978 |
+
if (options.reverse) {
|
12979 |
+
ticks.reverse();
|
12980 |
+
}
|
12981 |
+
return ticksFromTimestamps(this, ticks, this._majorUnit);
|
12982 |
+
}
|
12983 |
+
initOffsets(timestamps) {
|
12984 |
+
let start = 0;
|
12985 |
+
let end = 0;
|
12986 |
+
let first, last;
|
12987 |
+
if (this.options.offset && timestamps.length) {
|
12988 |
+
first = this.getDecimalForValue(timestamps[0]);
|
12989 |
+
if (timestamps.length === 1) {
|
12990 |
+
start = 1 - first;
|
12991 |
+
} else {
|
12992 |
+
start = (this.getDecimalForValue(timestamps[1]) - first) / 2;
|
12993 |
+
}
|
12994 |
+
last = this.getDecimalForValue(timestamps[timestamps.length - 1]);
|
12995 |
+
if (timestamps.length === 1) {
|
12996 |
+
end = last;
|
12997 |
+
} else {
|
12998 |
+
end = (last - this.getDecimalForValue(timestamps[timestamps.length - 2])) / 2;
|
12999 |
+
}
|
13000 |
+
}
|
13001 |
+
const limit = timestamps.length < 3 ? 0.5 : 0.25;
|
13002 |
+
start = _limitValue(start, 0, limit);
|
13003 |
+
end = _limitValue(end, 0, limit);
|
13004 |
+
this._offsets = {start, end, factor: 1 / (start + 1 + end)};
|
13005 |
+
}
|
13006 |
+
_generate() {
|
13007 |
+
const adapter = this._adapter;
|
13008 |
+
const min = this.min;
|
13009 |
+
const max = this.max;
|
13010 |
+
const options = this.options;
|
13011 |
+
const timeOpts = options.time;
|
13012 |
+
const minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, this._getLabelCapacity(min));
|
13013 |
+
const stepSize = valueOrDefault(timeOpts.stepSize, 1);
|
13014 |
+
const weekday = minor === 'week' ? timeOpts.isoWeekday : false;
|
13015 |
+
const hasWeekday = isNumber(weekday) || weekday === true;
|
13016 |
+
const ticks = {};
|
13017 |
+
let first = min;
|
13018 |
+
let time, count;
|
13019 |
+
if (hasWeekday) {
|
13020 |
+
first = +adapter.startOf(first, 'isoWeek', weekday);
|
13021 |
+
}
|
13022 |
+
first = +adapter.startOf(first, hasWeekday ? 'day' : minor);
|
13023 |
+
if (adapter.diff(max, min, minor) > 100000 * stepSize) {
|
13024 |
+
throw new Error(min + ' and ' + max + ' are too far apart with stepSize of ' + stepSize + ' ' + minor);
|
13025 |
+
}
|
13026 |
+
const timestamps = options.ticks.source === 'data' && this.getDataTimestamps();
|
13027 |
+
for (time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++) {
|
13028 |
+
addTick(ticks, time, timestamps);
|
13029 |
+
}
|
13030 |
+
if (time === max || options.bounds === 'ticks' || count === 1) {
|
13031 |
+
addTick(ticks, time, timestamps);
|
13032 |
+
}
|
13033 |
+
return Object.keys(ticks).sort((a, b) => a - b).map(x => +x);
|
13034 |
+
}
|
13035 |
+
getLabelForValue(value) {
|
13036 |
+
const adapter = this._adapter;
|
13037 |
+
const timeOpts = this.options.time;
|
13038 |
+
if (timeOpts.tooltipFormat) {
|
13039 |
+
return adapter.format(value, timeOpts.tooltipFormat);
|
13040 |
+
}
|
13041 |
+
return adapter.format(value, timeOpts.displayFormats.datetime);
|
13042 |
+
}
|
13043 |
+
_tickFormatFunction(time, index, ticks, format) {
|
13044 |
+
const options = this.options;
|
13045 |
+
const formats = options.time.displayFormats;
|
13046 |
+
const unit = this._unit;
|
13047 |
+
const majorUnit = this._majorUnit;
|
13048 |
+
const minorFormat = unit && formats[unit];
|
13049 |
+
const majorFormat = majorUnit && formats[majorUnit];
|
13050 |
+
const tick = ticks[index];
|
13051 |
+
const major = majorUnit && majorFormat && tick && tick.major;
|
13052 |
+
const label = this._adapter.format(time, format || (major ? majorFormat : minorFormat));
|
13053 |
+
const formatter = options.ticks.callback;
|
13054 |
+
return formatter ? callback(formatter, [label, index, ticks], this) : label;
|
13055 |
+
}
|
13056 |
+
generateTickLabels(ticks) {
|
13057 |
+
let i, ilen, tick;
|
13058 |
+
for (i = 0, ilen = ticks.length; i < ilen; ++i) {
|
13059 |
+
tick = ticks[i];
|
13060 |
+
tick.label = this._tickFormatFunction(tick.value, i, ticks);
|
13061 |
+
}
|
13062 |
+
}
|
13063 |
+
getDecimalForValue(value) {
|
13064 |
+
return value === null ? NaN : (value - this.min) / (this.max - this.min);
|
13065 |
+
}
|
13066 |
+
getPixelForValue(value) {
|
13067 |
+
const offsets = this._offsets;
|
13068 |
+
const pos = this.getDecimalForValue(value);
|
13069 |
+
return this.getPixelForDecimal((offsets.start + pos) * offsets.factor);
|
13070 |
+
}
|
13071 |
+
getValueForPixel(pixel) {
|
13072 |
+
const offsets = this._offsets;
|
13073 |
+
const pos = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end;
|
13074 |
+
return this.min + pos * (this.max - this.min);
|
13075 |
+
}
|
13076 |
+
_getLabelSize(label) {
|
13077 |
+
const ticksOpts = this.options.ticks;
|
13078 |
+
const tickLabelWidth = this.ctx.measureText(label).width;
|
13079 |
+
const angle = toRadians(this.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation);
|
13080 |
+
const cosRotation = Math.cos(angle);
|
13081 |
+
const sinRotation = Math.sin(angle);
|
13082 |
+
const tickFontSize = this._resolveTickFontOptions(0).size;
|
13083 |
+
return {
|
13084 |
+
w: (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation),
|
13085 |
+
h: (tickLabelWidth * sinRotation) + (tickFontSize * cosRotation)
|
13086 |
+
};
|
13087 |
+
}
|
13088 |
+
_getLabelCapacity(exampleTime) {
|
13089 |
+
const timeOpts = this.options.time;
|
13090 |
+
const displayFormats = timeOpts.displayFormats;
|
13091 |
+
const format = displayFormats[timeOpts.unit] || displayFormats.millisecond;
|
13092 |
+
const exampleLabel = this._tickFormatFunction(exampleTime, 0, ticksFromTimestamps(this, [exampleTime], this._majorUnit), format);
|
13093 |
+
const size = this._getLabelSize(exampleLabel);
|
13094 |
+
const capacity = Math.floor(this.isHorizontal() ? this.width / size.w : this.height / size.h) - 1;
|
13095 |
+
return capacity > 0 ? capacity : 1;
|
13096 |
+
}
|
13097 |
+
getDataTimestamps() {
|
13098 |
+
let timestamps = this._cache.data || [];
|
13099 |
+
let i, ilen;
|
13100 |
+
if (timestamps.length) {
|
13101 |
+
return timestamps;
|
13102 |
+
}
|
13103 |
+
const metas = this.getMatchingVisibleMetas();
|
13104 |
+
if (this._normalized && metas.length) {
|
13105 |
+
return (this._cache.data = metas[0].controller.getAllParsedValues(this));
|
13106 |
+
}
|
13107 |
+
for (i = 0, ilen = metas.length; i < ilen; ++i) {
|
13108 |
+
timestamps = timestamps.concat(metas[i].controller.getAllParsedValues(this));
|
13109 |
+
}
|
13110 |
+
return (this._cache.data = this.normalize(timestamps));
|
13111 |
+
}
|
13112 |
+
getLabelTimestamps() {
|
13113 |
+
const timestamps = this._cache.labels || [];
|
13114 |
+
let i, ilen;
|
13115 |
+
if (timestamps.length) {
|
13116 |
+
return timestamps;
|
13117 |
+
}
|
13118 |
+
const labels = this.getLabels();
|
13119 |
+
for (i = 0, ilen = labels.length; i < ilen; ++i) {
|
13120 |
+
timestamps.push(parse(this, labels[i]));
|
13121 |
+
}
|
13122 |
+
return (this._cache.labels = this._normalized ? timestamps : this.normalize(timestamps));
|
13123 |
+
}
|
13124 |
+
normalize(values) {
|
13125 |
+
return _arrayUnique(values.sort(sorter));
|
13126 |
+
}
|
13127 |
+
}
|
13128 |
+
TimeScale.id = 'time';
|
13129 |
+
TimeScale.defaults = {
|
13130 |
+
bounds: 'data',
|
13131 |
+
adapters: {},
|
13132 |
+
time: {
|
13133 |
+
parser: false,
|
13134 |
+
unit: false,
|
13135 |
+
round: false,
|
13136 |
+
isoWeekday: false,
|
13137 |
+
minUnit: 'millisecond',
|
13138 |
+
displayFormats: {}
|
13139 |
+
},
|
13140 |
+
ticks: {
|
13141 |
+
source: 'auto',
|
13142 |
+
major: {
|
13143 |
+
enabled: false
|
13144 |
+
}
|
13145 |
+
}
|
13146 |
+
};
|
13147 |
+
|
13148 |
+
function interpolate(table, val, reverse) {
|
13149 |
+
let lo = 0;
|
13150 |
+
let hi = table.length - 1;
|
13151 |
+
let prevSource, nextSource, prevTarget, nextTarget;
|
13152 |
+
if (reverse) {
|
13153 |
+
if (val >= table[lo].pos && val <= table[hi].pos) {
|
13154 |
+
({lo, hi} = _lookupByKey(table, 'pos', val));
|
13155 |
+
}
|
13156 |
+
({pos: prevSource, time: prevTarget} = table[lo]);
|
13157 |
+
({pos: nextSource, time: nextTarget} = table[hi]);
|
13158 |
+
} else {
|
13159 |
+
if (val >= table[lo].time && val <= table[hi].time) {
|
13160 |
+
({lo, hi} = _lookupByKey(table, 'time', val));
|
13161 |
+
}
|
13162 |
+
({time: prevSource, pos: prevTarget} = table[lo]);
|
13163 |
+
({time: nextSource, pos: nextTarget} = table[hi]);
|
13164 |
+
}
|
13165 |
+
const span = nextSource - prevSource;
|
13166 |
+
return span ? prevTarget + (nextTarget - prevTarget) * (val - prevSource) / span : prevTarget;
|
13167 |
+
}
|
13168 |
+
class TimeSeriesScale extends TimeScale {
|
13169 |
+
constructor(props) {
|
13170 |
+
super(props);
|
13171 |
+
this._table = [];
|
13172 |
+
this._minPos = undefined;
|
13173 |
+
this._tableRange = undefined;
|
13174 |
+
}
|
13175 |
+
initOffsets() {
|
13176 |
+
const timestamps = this._getTimestampsForTable();
|
13177 |
+
const table = this._table = this.buildLookupTable(timestamps);
|
13178 |
+
this._minPos = interpolate(table, this.min);
|
13179 |
+
this._tableRange = interpolate(table, this.max) - this._minPos;
|
13180 |
+
super.initOffsets(timestamps);
|
13181 |
+
}
|
13182 |
+
buildLookupTable(timestamps) {
|
13183 |
+
const {min, max} = this;
|
13184 |
+
const items = [];
|
13185 |
+
const table = [];
|
13186 |
+
let i, ilen, prev, curr, next;
|
13187 |
+
for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
|
13188 |
+
curr = timestamps[i];
|
13189 |
+
if (curr >= min && curr <= max) {
|
13190 |
+
items.push(curr);
|
13191 |
+
}
|
13192 |
+
}
|
13193 |
+
if (items.length < 2) {
|
13194 |
+
return [
|
13195 |
+
{time: min, pos: 0},
|
13196 |
+
{time: max, pos: 1}
|
13197 |
+
];
|
13198 |
+
}
|
13199 |
+
for (i = 0, ilen = items.length; i < ilen; ++i) {
|
13200 |
+
next = items[i + 1];
|
13201 |
+
prev = items[i - 1];
|
13202 |
+
curr = items[i];
|
13203 |
+
if (Math.round((next + prev) / 2) !== curr) {
|
13204 |
+
table.push({time: curr, pos: i / (ilen - 1)});
|
13205 |
+
}
|
13206 |
+
}
|
13207 |
+
return table;
|
13208 |
+
}
|
13209 |
+
_getTimestampsForTable() {
|
13210 |
+
let timestamps = this._cache.all || [];
|
13211 |
+
if (timestamps.length) {
|
13212 |
+
return timestamps;
|
13213 |
+
}
|
13214 |
+
const data = this.getDataTimestamps();
|
13215 |
+
const label = this.getLabelTimestamps();
|
13216 |
+
if (data.length && label.length) {
|
13217 |
+
timestamps = this.normalize(data.concat(label));
|
13218 |
+
} else {
|
13219 |
+
timestamps = data.length ? data : label;
|
13220 |
+
}
|
13221 |
+
timestamps = this._cache.all = timestamps;
|
13222 |
+
return timestamps;
|
13223 |
+
}
|
13224 |
+
getDecimalForValue(value) {
|
13225 |
+
return (interpolate(this._table, value) - this._minPos) / this._tableRange;
|
13226 |
+
}
|
13227 |
+
getValueForPixel(pixel) {
|
13228 |
+
const offsets = this._offsets;
|
13229 |
+
const decimal = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end;
|
13230 |
+
return interpolate(this._table, decimal * this._tableRange + this._minPos, true);
|
13231 |
+
}
|
13232 |
+
}
|
13233 |
+
TimeSeriesScale.id = 'timeseries';
|
13234 |
+
TimeSeriesScale.defaults = TimeScale.defaults;
|
13235 |
+
|
13236 |
+
var scales = /*#__PURE__*/Object.freeze({
|
13237 |
+
__proto__: null,
|
13238 |
+
CategoryScale: CategoryScale,
|
13239 |
+
LinearScale: LinearScale,
|
13240 |
+
LogarithmicScale: LogarithmicScale,
|
13241 |
+
RadialLinearScale: RadialLinearScale,
|
13242 |
+
TimeScale: TimeScale,
|
13243 |
+
TimeSeriesScale: TimeSeriesScale
|
13244 |
+
});
|
13245 |
+
|
13246 |
+
Chart.register(controllers, scales, elements, plugins);
|
13247 |
+
Chart.helpers = {...helpers};
|
13248 |
+
Chart._adapters = _adapters;
|
13249 |
+
Chart.Animation = Animation;
|
13250 |
+
Chart.Animations = Animations;
|
13251 |
+
Chart.animator = animator;
|
13252 |
+
Chart.controllers = registry.controllers.items;
|
13253 |
+
Chart.DatasetController = DatasetController;
|
13254 |
+
Chart.Element = Element;
|
13255 |
+
Chart.elements = elements;
|
13256 |
+
Chart.Interaction = Interaction;
|
13257 |
+
Chart.layouts = layouts;
|
13258 |
+
Chart.platforms = platforms;
|
13259 |
+
Chart.Scale = Scale;
|
13260 |
+
Chart.Ticks = Ticks;
|
13261 |
+
Object.assign(Chart, controllers, scales, elements, plugins, platforms);
|
13262 |
+
Chart.Chart = Chart;
|
13263 |
+
if (typeof window !== 'undefined') {
|
13264 |
+
window.Chart = Chart;
|
13265 |
+
}
|
13266 |
+
|
13267 |
+
return Chart;
|
13268 |
+
|
13269 |
+
}));
|
@@ -1,10 +1,13 @@
|
|
1 |
/*!
|
2 |
-
* Chart.js
|
3 |
-
*
|
4 |
-
*
|
5 |
-
*
|
6 |
-
* Copyright 2017 Nick Downie
|
7 |
-
* Released under the MIT license
|
8 |
-
* https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
|
9 |
*/
|
10 |
-
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chart=t()}}(function(){return function t(e,n,i){function a(o,s){if(!n[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[o]={exports:{}};e[o][0].call(d.exports,function(t){var n=e[o][1][t];return a(n||t)},d,d.exports,t,e,n,i)}return n[o].exports}for(var r="function"==typeof require&&require,o=0;o<i.length;o++)a(i[o]);return a}({1:[function(t,e,n){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/i,n=/^#([a-fA-F0-9]{6})$/i,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,a=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,r=/(\w+)/,o=[0,0,0],s=1,l=t.match(e);if(l){l=l[1];for(d=0;d<o.length;d++)o[d]=parseInt(l[d]+l[d],16)}else if(l=t.match(n)){l=l[1];for(d=0;d<o.length;d++)o[d]=parseInt(l.slice(2*d,2*d+2),16)}else if(l=t.match(i)){for(d=0;d<o.length;d++)o[d]=parseInt(l[d+1]);s=parseFloat(l[4])}else if(l=t.match(a)){for(d=0;d<o.length;d++)o[d]=Math.round(2.55*parseFloat(l[d+1]));s=parseFloat(l[4])}else if(l=t.match(r)){if("transparent"==l[1])return[0,0,0,0];if(!(o=c[l[1]]))return}for(var d=0;d<o.length;d++)o[d]=u(o[d],0,255);return s=s||0==s?u(s,0,1):1,o[3]=s,o}}function a(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]);return[u(parseInt(n[1]),0,360),u(parseFloat(n[2]),0,100),u(parseFloat(n[3]),0,100),u(isNaN(i)?1:i,0,1)]}}}function r(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]);return[u(parseInt(n[1]),0,360),u(parseFloat(n[2]),0,100),u(parseFloat(n[3]),0,100),u(isNaN(i)?1:i,0,1)]}}}function o(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function s(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 l(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function u(t,e,n){return Math.min(Math.max(e,t),n)}function d(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var c=t(5);e.exports={getRgba:i,getHsla:a,getRgb:function(t){var e=i(t);return e&&e.slice(0,3)},getHsl:function(t){var e=a(t);return e&&e.slice(0,3)},getHwb:r,getAlpha:function(t){var e=i(t);return e?e[3]:(e=a(t))?e[3]:(e=r(t))?e[3]:void 0},hexString:function(t){return"#"+d(t[0])+d(t[1])+d(t[2])},rgbString:function(t,e){return e<1||t[3]&&t[3]<1?o(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:o,percentString:function(t,e){return e<1||t[3]&&t[3]<1?s(t,e):"rgb("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%)"},percentaString:s,hslString:function(t,e){return e<1||t[3]&&t[3]<1?l(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:l,hwbString:function(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return h[t.slice(0,3)]}};var h={};for(var f in c)h[c[f]]=f},{5:5}],2:[function(t,e,n){var i=t(4),a=t(1),r=function(t){if(t instanceof r)return t;if(!(this instanceof r))return new r(t);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};var e;"string"==typeof t?(e=a.getRgba(t))?this.setValues("rgb",e):(e=a.getHsla(t))?this.setValues("hsl",e):(e=a.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))};r.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 a.hexString(this.values.rgb)},rgbString:function(){return a.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return a.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return a.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return a.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return a.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return a.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return a.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=this,i=t,a=void 0===e?.5:e,r=2*a-1,o=n.alpha()-i.alpha(),s=((r*o==-1?r:(r+o)/(1+r*o))+1)/2,l=1-s;return this.rgb(s*n.red()+l*i.red(),s*n.green()+l*i.green(),s*n.blue()+l*i.blue()).alpha(n.alpha()*a+i.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new r,i=this.values,a=n.values;for(var o in i)i.hasOwnProperty(o)&&(t=i[o],"[object Array]"===(e={}.toString.call(t))?a[o]=t.slice(0):"[object Number]"===e?a[o]=t:console.error("unexpected color value:",t));return n}},r.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},r.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},r.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},r.prototype.setValues=function(t,e){var n,a=this.values,r=this.spaces,o=this.maxes,s=1;if(this.valid=!0,"alpha"===t)s=e;else if(e.length)a[t]=e.slice(0,t.length),s=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)];s=e.a}else if(void 0!==e[r[t][0]]){var l=r[t];for(n=0;n<t.length;n++)a[t][n]=e[l[n]];s=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===s?a.alpha:s)),"alpha"===t)return!1;var u;for(n=0;n<t.length;n++)u=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(u);for(var d in r)d!==t&&(a[d]=i[t][d](a[t]));return!0},r.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)},r.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=r),e.exports=r},{1:1,4:4}],3:[function(t,e,n){function i(t){var e,n,i,a=t[0]/255,r=t[1]/255,o=t[2]/255,s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),(e=Math.min(60*e,360))<0&&(e+=360),i=(s+l)/2,n=l==s?0:i<=.5?u/(l+s):u/(2-l-s),[e,100*n,100*i]}function a(t){var e,n,i,a=t[0],r=t[1],o=t[2],s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return n=0==l?0:u/l*1e3/10,l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),(e=Math.min(60*e,360))<0&&(e+=360),i=l/255*1e3/10,[e,n,i]}function o(t){var e=t[0],n=t[1],a=t[2];return[i(t)[0],100*(1/255*Math.min(e,Math.min(n,a))),100*(a=1-1/255*Math.max(e,Math.max(n,a)))]}function s(t){var e,n,i,a,r=t[0]/255,o=t[1]/255,s=t[2]/255;return a=Math.min(1-r,1-o,1-s),e=(1-r-a)/(1-a)||0,n=(1-o-a)/(1-a)||0,i=(1-s-a)/(1-a)||0,[100*e,100*n,100*i,100*a]}function l(t){return S[JSON.stringify(t)]}function u(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)]}function d(t){var e,n,i,a=u(t),r=a[0],o=a[1],s=a[2];return r/=95.047,o/=100,s/=108.883,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,e=116*o-16,n=500*(r-o),i=200*(o-s),[e,n,i]}function c(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,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}function h(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)),i=255*i;switch(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]}}function f(t){var e,n,i,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),e=Math.floor(6*o),n=1-l,i=6*o-e,0!=(1&e)&&(i=1-i),a=s+i*(n-s),e){default:case 6:case 0:r=n,g=a,b=s;break;case 1:r=a,g=n,b=s;break;case 2:r=s,g=n,b=a;break;case 3:r=s,g=a,b=n;break;case 4:r=a,g=s,b=n;break;case 5:r=n,g=s,b=a}return[255*r,255*g,255*b]}function m(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100,s=t[3]/100;return e=1-Math.min(1,a*(1-s)+s),n=1-Math.min(1,r*(1-s)+s),i=1-Math.min(1,o*(1-s)+s),[255*e,255*n,255*i]}function p(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return e=3.2406*a+-1.5372*r+-.4986*o,n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,e=Math.min(Math.max(0,e),1),n=Math.min(Math.max(0,n),1),i=Math.min(Math.max(0,i),1),[255*e,255*n,255*i]}function v(t){var e,n,i,a=t[0],r=t[1],o=t[2];return a/=95.047,r/=100,o/=108.883,a=a>.008856?Math.pow(a,1/3):7.787*a+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,e=116*r-16,n=500*(a-r),i=200*(r-o),[e,n,i]}function y(t){var e,n,i,a,r=t[0],o=t[1],s=t[2];return r<=8?a=(n=100*r/903.3)/100*7.787+16/116:(n=100*Math.pow((r+16)/116,3),a=Math.pow(n/100,1/3)),e=e/95.047<=.008856?e=95.047*(o/500+a-16/116)/7.787:95.047*Math.pow(o/500+a,3),i=i/108.883<=.008859?i=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3),[e,n,i]}function x(t){var e,n,i,a=t[0],r=t[1],o=t[2];return e=Math.atan2(o,r),(n=360*e/2/Math.PI)<0&&(n+=360),i=Math.sqrt(r*r+o*o),[a,i,n]}function _(t){return p(y(t))}function k(t){var e,n,i,a=t[0],r=t[1];return i=t[2]/360*2*Math.PI,e=r*Math.cos(i),n=r*Math.sin(i),[a,e,n]}function w(t){return M[t]}e.exports={rgb2hsl:i,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:function(t){return x(d(t))},hsl2rgb:c,hsl2hsv:function(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return 0===r?[0,0,0]:(r*=2,a*=r<=1?r:2-r,n=(r+a)/2,e=2*a/(r+a),[i,100*e,100*n])},hsl2hwb:function(t){return o(c(t))},hsl2cmyk:function(t){return s(c(t))},hsl2keyword:function(t){return l(c(t))},hsv2rgb:h,hsv2hsl:function(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return n=(2-a)*r,e=a*r,e/=n<=1?n:2-n,e=e||0,n/=2,[i,100*e,100*n]},hsv2hwb:function(t){return o(h(t))},hsv2cmyk:function(t){return s(h(t))},hsv2keyword:function(t){return l(h(t))},hwb2rgb:f,hwb2hsl:function(t){return i(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return l(f(t))},cmyk2rgb:m,cmyk2hsl:function(t){return i(m(t))},cmyk2hsv:function(t){return a(m(t))},cmyk2hwb:function(t){return o(m(t))},cmyk2keyword:function(t){return l(m(t))},keyword2rgb:w,keyword2hsl:function(t){return i(w(t))},keyword2hsv:function(t){return a(w(t))},keyword2hwb:function(t){return o(w(t))},keyword2cmyk:function(t){return s(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return u(w(t))},xyz2rgb:p,xyz2lab:v,xyz2lch:function(t){return x(v(t))},lab2xyz:y,lab2rgb:_,lab2lch:x,lch2lab:k,lch2xyz:function(t){return y(k(t))},lch2rgb:function(t){return _(k(t))}};var M={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]},S={};for(var D in M)S[JSON.stringify(M[D])]=D},{}],4:[function(t,e,n){var i=t(3),a=function(){return new u};for(var r in i){a[r+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(r);var o=/(\w+)2(\w+)/.exec(r),s=o[1],l=o[2];(a[s]=a[s]||{})[l]=a[r]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var n=i[t](e);if("string"==typeof n||void 0===n)return n;for(var a=0;a<n.length;a++)n[a]=Math.round(n[a]);return n}}(r)}var u=function(){this.convs={}};u.prototype.routeSpace=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))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var n=this.space,i=this.convs[n];e=a[n][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=a},{3:3}],5:[function(t,e,n){"use strict";e.exports={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]}},{}],6:[function(t,e,n){!function(t,i){"object"==typeof n&&void 0!==e?e.exports=i():t.moment=i()}(this,function(){"use strict";function n(){return xe.apply(null,arguments)}function i(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function a(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function r(t){var e;for(e in t)return!1;return!0}function o(t){return void 0===t}function s(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function l(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function u(t,e){var n,i=[];for(n=0;n<t.length;++n)i.push(e(t[n],n));return i}function d(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function c(t,e){for(var n in e)d(e,n)&&(t[n]=e[n]);return d(e,"toString")&&(t.toString=e.toString),d(e,"valueOf")&&(t.valueOf=e.valueOf),t}function h(t,e,n,i){return Yt(t,e,n,i,!0).utc()}function f(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}}function g(t){return null==t._pf&&(t._pf=f()),t._pf}function m(t){if(null==t._isValid){var e=g(t),n=ke.call(e.parsedDateParts,function(t){return null!=t}),i=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n);if(t._strict&&(i=i&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return i;t._isValid=i}return t._isValid}function p(t){var e=h(NaN);return null!=t?c(g(e),t):g(e).userInvalidated=!0,e}function v(t,e){var n,i,a;if(o(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),o(e._i)||(t._i=e._i),o(e._f)||(t._f=e._f),o(e._l)||(t._l=e._l),o(e._strict)||(t._strict=e._strict),o(e._tzm)||(t._tzm=e._tzm),o(e._isUTC)||(t._isUTC=e._isUTC),o(e._offset)||(t._offset=e._offset),o(e._pf)||(t._pf=g(e)),o(e._locale)||(t._locale=e._locale),we.length>0)for(n=0;n<we.length;n++)o(a=e[i=we[n]])||(t[i]=a);return t}function y(t){v(this,t),this._d=new Date(null!=t._d?t._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===Me&&(Me=!0,n.updateOffset(this),Me=!1)}function b(t){return t instanceof y||null!=t&&null!=t._isAMomentObject}function x(t){return t<0?Math.ceil(t)||0:Math.floor(t)}function _(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=x(e)),n}function k(t,e,n){var i,a=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),o=0;for(i=0;i<a;i++)(n&&t[i]!==e[i]||!n&&_(t[i])!==_(e[i]))&&o++;return o+r}function w(t){!1===n.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function M(t,e){var i=!0;return c(function(){if(null!=n.deprecationHandler&&n.deprecationHandler(null,t),i){for(var a,r=[],o=0;o<arguments.length;o++){if(a="","object"==typeof arguments[o]){a+="\n["+o+"] ";for(var s in arguments[0])a+=s+": "+arguments[0][s]+", ";a=a.slice(0,-2)}else a=arguments[o];r.push(a)}w(t+"\nArguments: "+Array.prototype.slice.call(r).join("")+"\n"+(new Error).stack),i=!1}return e.apply(this,arguments)},e)}function S(t,e){null!=n.deprecationHandler&&n.deprecationHandler(t,e),Se[t]||(w(e),Se[t]=!0)}function D(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function C(t,e){var n,i=c({},t);for(n in e)d(e,n)&&(a(t[n])&&a(e[n])?(i[n]={},c(i[n],t[n]),c(i[n],e[n])):null!=e[n]?i[n]=e[n]:delete i[n]);for(n in t)d(t,n)&&!d(e,n)&&a(t[n])&&(i[n]=c({},i[n]));return i}function P(t){null!=t&&this.set(t)}function T(t,e){var n=t.toLowerCase();Fe[n]=Fe[n+"s"]=Fe[e]=t}function I(t){return"string"==typeof t?Fe[t]||Fe[t.toLowerCase()]:void 0}function A(t){var e,n,i={};for(n in t)d(t,n)&&(e=I(n))&&(i[e]=t[n]);return i}function O(t,e){Re[t]=e}function F(t){var e=[];for(var n in t)e.push({unit:n,priority:Re[n]});return e.sort(function(t,e){return t.priority-e.priority}),e}function R(t,e){return function(i){return null!=i?(W(this,t,i),n.updateOffset(this,e),this):L(this,t)}}function L(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function W(t,e,n){t.isValid()&&t._d["set"+(t._isUTC?"UTC":"")+e](n)}function Y(t,e,n){var i=""+Math.abs(t),a=e-i.length;return(t>=0?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}function N(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(Ne[t]=a),e&&(Ne[e[0]]=function(){return Y(a.apply(this,arguments),e[1],e[2])}),n&&(Ne[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function z(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function B(t){var e,n,i=t.match(Le);for(e=0,n=i.length;e<n;e++)Ne[i[e]]?i[e]=Ne[i[e]]:i[e]=z(i[e]);return function(e){var a,r="";for(a=0;a<n;a++)r+=D(i[a])?i[a].call(e,t):i[a];return r}}function V(t,e){return t.isValid()?(e=H(e,t.localeData()),Ye[e]=Ye[e]||B(e),Ye[e](t)):t.localeData().invalidDate()}function H(t,e){var n=5;for(We.lastIndex=0;n>=0&&We.test(t);)t=t.replace(We,function(t){return e.longDateFormat(t)||t}),We.lastIndex=0,n-=1;return t}function E(t,e,n){nn[t]=D(e)?e:function(t,i){return t&&n?n:e}}function j(t,e){return d(nn,t)?nn[t](e._strict,e._locale):new RegExp(U(t))}function U(t){return q(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,a){return e||n||i||a}))}function q(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function G(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),s(e)&&(i=function(t,n){n[e]=_(t)}),n=0;n<t.length;n++)an[t[n]]=i}function Z(t,e){G(t,function(t,n,i,a){i._w=i._w||{},e(t,i._w,i,a)})}function X(t,e,n){null!=e&&d(an,t)&&an[t](e,n._a,n,t)}function J(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function K(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;i<12;++i)r=h([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===e?-1!==(a=gn.call(this._shortMonthsParse,o))?a:null:-1!==(a=gn.call(this._longMonthsParse,o))?a:null:"MMM"===e?-1!==(a=gn.call(this._shortMonthsParse,o))?a:-1!==(a=gn.call(this._longMonthsParse,o))?a:null:-1!==(a=gn.call(this._longMonthsParse,o))?a:-1!==(a=gn.call(this._shortMonthsParse,o))?a:null}function Q(t,e){var n;if(!t.isValid())return t;if("string"==typeof e)if(/^\d+$/.test(e))e=_(e);else if(e=t.localeData().monthsParse(e),!s(e))return t;return n=Math.min(t.date(),J(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n),t}function $(t){return null!=t?(Q(this,t),n.updateOffset(this,!0),this):L(this,"Month")}function tt(){function t(t,e){return e.length-t.length}var e,n,i=[],a=[],r=[];for(e=0;e<12;e++)n=h([2e3,e]),i.push(this.monthsShort(n,"")),a.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(i.sort(t),a.sort(t),r.sort(t),e=0;e<12;e++)i[e]=q(i[e]),a[e]=q(a[e]);for(e=0;e<24;e++)r[e]=q(r[e]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+i.join("|")+")","i")}function et(t){return nt(t)?366:365}function nt(t){return t%4==0&&t%100!=0||t%400==0}function it(t,e,n,i,a,r,o){var s=new Date(t,e,n,i,a,r,o);return t<100&&t>=0&&isFinite(s.getFullYear())&&s.setFullYear(t),s}function at(t){var e=new Date(Date.UTC.apply(null,arguments));return t<100&&t>=0&&isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t),e}function rt(t,e,n){var i=7+e-n;return-((7+at(t,0,i).getUTCDay()-e)%7)+i-1}function ot(t,e,n,i,a){var r,o,s=1+7*(e-1)+(7+n-i)%7+rt(t,i,a);return s<=0?o=et(r=t-1)+s:s>et(t)?(r=t+1,o=s-et(t)):(r=t,o=s),{year:r,dayOfYear:o}}function st(t,e,n){var i,a,r=rt(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return o<1?i=o+lt(a=t.year()-1,e,n):o>lt(t.year(),e,n)?(i=o-lt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function lt(t,e,n){var i=rt(t,e,n),a=rt(t+1,e,n);return(et(t)-i+a)/7}function ut(t,e){return"string"!=typeof t?t:isNaN(t)?"number"==typeof(t=e.weekdaysParse(t))?t:null:parseInt(t,10)}function dt(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}function ct(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=h([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(a=gn.call(this._weekdaysParse,o))?a:null:"ddd"===e?-1!==(a=gn.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=gn.call(this._minWeekdaysParse,o))?a:null:"dddd"===e?-1!==(a=gn.call(this._weekdaysParse,o))?a:-1!==(a=gn.call(this._shortWeekdaysParse,o))?a:-1!==(a=gn.call(this._minWeekdaysParse,o))?a:null:"ddd"===e?-1!==(a=gn.call(this._shortWeekdaysParse,o))?a:-1!==(a=gn.call(this._weekdaysParse,o))?a:-1!==(a=gn.call(this._minWeekdaysParse,o))?a:null:-1!==(a=gn.call(this._minWeekdaysParse,o))?a:-1!==(a=gn.call(this._weekdaysParse,o))?a:-1!==(a=gn.call(this._shortWeekdaysParse,o))?a:null}function ht(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;e<7;e++)n=h([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;e<7;e++)s[e]=q(s[e]),l[e]=q(l[e]),u[e]=q(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function ft(){return this.hours()%12||12}function gt(t,e){N(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function mt(t,e){return e._meridiemParse}function pt(t){return t?t.toLowerCase().replace("_","-"):t}function vt(t){for(var e,n,i,a,r=0;r<t.length;){for(e=(a=pt(t[r]).split("-")).length,n=(n=pt(t[r+1]))?n.split("-"):null;e>0;){if(i=yt(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&k(a,n,!0)>=e-1)break;e--}r++}return null}function yt(n){var i=null;if(!On[n]&&void 0!==e&&e&&e.exports)try{i=Pn._abbr,t("./locale/"+n),bt(i)}catch(t){}return On[n]}function bt(t,e){var n;return t&&(n=o(e)?_t(t):xt(t,e))&&(Pn=n),Pn._abbr}function xt(t,e){if(null!==e){var n=An;if(e.abbr=t,null!=On[t])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),n=On[t]._config;else if(null!=e.parentLocale){if(null==On[e.parentLocale])return Fn[e.parentLocale]||(Fn[e.parentLocale]=[]),Fn[e.parentLocale].push({name:t,config:e}),null;n=On[e.parentLocale]._config}return On[t]=new P(C(n,e)),Fn[t]&&Fn[t].forEach(function(t){xt(t.name,t.config)}),bt(t),On[t]}return delete On[t],null}function _t(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return Pn;if(!i(t)){if(e=yt(t))return e;t=[t]}return vt(t)}function kt(t){var e,n=t._a;return n&&-2===g(t).overflow&&(e=n[on]<0||n[on]>11?on:n[sn]<1||n[sn]>J(n[rn],n[on])?sn:n[ln]<0||n[ln]>24||24===n[ln]&&(0!==n[un]||0!==n[dn]||0!==n[cn])?ln:n[un]<0||n[un]>59?un:n[dn]<0||n[dn]>59?dn:n[cn]<0||n[cn]>999?cn:-1,g(t)._overflowDayOfYear&&(e<rn||e>sn)&&(e=sn),g(t)._overflowWeeks&&-1===e&&(e=hn),g(t)._overflowWeekday&&-1===e&&(e=fn),g(t).overflow=e),t}function wt(t){var e,n,i,a,r,o,s=t._i,l=Rn.exec(s)||Ln.exec(s);if(l){for(g(t).iso=!0,e=0,n=Yn.length;e<n;e++)if(Yn[e][1].exec(l[1])){a=Yn[e][0],i=!1!==Yn[e][2];break}if(null==a)return void(t._isValid=!1);if(l[3]){for(e=0,n=Nn.length;e<n;e++)if(Nn[e][1].exec(l[3])){r=(l[2]||" ")+Nn[e][0];break}if(null==r)return void(t._isValid=!1)}if(!i&&null!=r)return void(t._isValid=!1);if(l[4]){if(!Wn.exec(l[4]))return void(t._isValid=!1);o="Z"}t._f=a+(r||"")+(o||""),It(t)}else t._isValid=!1}function Mt(t){var e,n,i,a,r,o,s,l,u={" GMT":" +0000"," EDT":" -0400"," EST":" -0500"," CDT":" -0500"," CST":" -0600"," MDT":" -0600"," MST":" -0700"," PDT":" -0700"," PST":" -0800"};if(e=t._i.replace(/\([^\)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s|\s$/g,""),n=Bn.exec(e)){if(i=n[1]?"ddd"+(5===n[1].length?", ":" "):"",a="D MMM "+(n[2].length>10?"YYYY ":"YY "),r="HH:mm"+(n[4]?":ss":""),n[1]){var d=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][new Date(n[2]).getDay()];if(n[1].substr(0,3)!==d)return g(t).weekdayMismatch=!0,void(t._isValid=!1)}switch(n[5].length){case 2:s=0===l?" +0000":((l="YXWVUTSRQPONZABCDEFGHIKLM".indexOf(n[5][1].toUpperCase())-12)<0?" -":" +")+(""+l).replace(/^-?/,"0").match(/..$/)[0]+"00";break;case 4:s=u[n[5]];break;default:s=u[" GMT"]}n[5]=s,t._i=n.splice(1).join(""),o=" ZZ",t._f=i+a+r+o,It(t),g(t).rfc2822=!0}else t._isValid=!1}function St(t){var e=zn.exec(t._i);null===e?(wt(t),!1===t._isValid&&(delete t._isValid,Mt(t),!1===t._isValid&&(delete t._isValid,n.createFromInputFallback(t)))):t._d=new Date(+e[1])}function Dt(t,e,n){return null!=t?t:null!=e?e:n}function Ct(t){var e=new Date(n.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}function Pt(t){var e,n,i,a,r=[];if(!t._d){for(i=Ct(t),t._w&&null==t._a[sn]&&null==t._a[on]&&Tt(t),null!=t._dayOfYear&&(a=Dt(t._a[rn],i[rn]),(t._dayOfYear>et(a)||0===t._dayOfYear)&&(g(t)._overflowDayOfYear=!0),n=at(a,0,t._dayOfYear),t._a[on]=n.getUTCMonth(),t._a[sn]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=r[e]=i[e];for(;e<7;e++)t._a[e]=r[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[ln]&&0===t._a[un]&&0===t._a[dn]&&0===t._a[cn]&&(t._nextDay=!0,t._a[ln]=0),t._d=(t._useUTC?at:it).apply(null,r),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[ln]=24)}}function Tt(t){var e,n,i,a,r,o,s,l;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)r=1,o=4,n=Dt(e.GG,t._a[rn],st(Nt(),1,4).year),i=Dt(e.W,1),((a=Dt(e.E,1))<1||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=st(Nt(),r,o);n=Dt(e.gg,t._a[rn],u.year),i=Dt(e.w,u.week),null!=e.d?((a=e.d)<0||a>6)&&(l=!0):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}i<1||i>lt(n,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=ot(n,i,a,r,o),t._a[rn]=s.year,t._dayOfYear=s.dayOfYear)}function It(t){if(t._f!==n.ISO_8601)if(t._f!==n.RFC_2822){t._a=[],g(t).empty=!0;var e,i,a,r,o,s=""+t._i,l=s.length,u=0;for(a=H(t._f,t._locale).match(Le)||[],e=0;e<a.length;e++)r=a[e],(i=(s.match(j(r,t))||[])[0])&&((o=s.substr(0,s.indexOf(i))).length>0&&g(t).unusedInput.push(o),s=s.slice(s.indexOf(i)+i.length),u+=i.length),Ne[r]?(i?g(t).empty=!1:g(t).unusedTokens.push(r),X(r,i,t)):t._strict&&!i&&g(t).unusedTokens.push(r);g(t).charsLeftOver=l-u,s.length>0&&g(t).unusedInput.push(s),t._a[ln]<=12&&!0===g(t).bigHour&&t._a[ln]>0&&(g(t).bigHour=void 0),g(t).parsedDateParts=t._a.slice(0),g(t).meridiem=t._meridiem,t._a[ln]=At(t._locale,t._a[ln],t._meridiem),Pt(t),kt(t)}else Mt(t);else wt(t)}function At(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?((i=t.isPM(n))&&e<12&&(e+=12),i||12!==e||(e=0),e):e}function Ot(t){var e,n,i,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;a<t._f.length;a++)r=0,e=v({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[a],It(e),m(e)&&(r+=g(e).charsLeftOver,r+=10*g(e).unusedTokens.length,g(e).score=r,(null==i||r<i)&&(i=r,n=e));c(t,n||e)}function Ft(t){if(!t._d){var e=A(t._i);t._a=u([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],function(t){return t&&parseInt(t,10)}),Pt(t)}}function Rt(t){var e=new y(kt(Lt(t)));return e._nextDay&&(e.add(1,"d"),e._nextDay=void 0),e}function Lt(t){var e=t._i,n=t._f;return t._locale=t._locale||_t(t._l),null===e||void 0===n&&""===e?p({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),b(e)?new y(kt(e)):(l(e)?t._d=e:i(n)?Ot(t):n?It(t):Wt(t),m(t)||(t._d=null),t))}function Wt(t){var e=t._i;o(e)?t._d=new Date(n.now()):l(e)?t._d=new Date(e.valueOf()):"string"==typeof e?St(t):i(e)?(t._a=u(e.slice(0),function(t){return parseInt(t,10)}),Pt(t)):a(e)?Ft(t):s(e)?t._d=new Date(e):n.createFromInputFallback(t)}function Yt(t,e,n,o,s){var l={};return!0!==n&&!1!==n||(o=n,n=void 0),(a(t)&&r(t)||i(t)&&0===t.length)&&(t=void 0),l._isAMomentObject=!0,l._useUTC=l._isUTC=s,l._l=n,l._i=t,l._f=e,l._strict=o,Rt(l)}function Nt(t,e,n,i){return Yt(t,e,n,i,!1)}function zt(t,e){var n,a;if(1===e.length&&i(e[0])&&(e=e[0]),!e.length)return Nt();for(n=e[0],a=1;a<e.length;++a)e[a].isValid()&&!e[a][t](n)||(n=e[a]);return n}function Bt(t){for(var e in t)if(-1===En.indexOf(e)||null!=t[e]&&isNaN(t[e]))return!1;for(var n=!1,i=0;i<En.length;++i)if(t[En[i]]){if(n)return!1;parseFloat(t[En[i]])!==_(t[En[i]])&&(n=!0)}return!0}function Vt(t){var e=A(t),n=e.year||0,i=e.quarter||0,a=e.month||0,r=e.week||0,o=e.day||0,s=e.hour||0,l=e.minute||0,u=e.second||0,d=e.millisecond||0;this._isValid=Bt(e),this._milliseconds=+d+1e3*u+6e4*l+1e3*s*60*60,this._days=+o+7*r,this._months=+a+3*i+12*n,this._data={},this._locale=_t(),this._bubble()}function Ht(t){return t instanceof Vt}function Et(t){return t<0?-1*Math.round(-1*t):Math.round(t)}function jt(t,e){N(t,0,0,function(){var t=this.utcOffset(),n="+";return t<0&&(t=-t,n="-"),n+Y(~~(t/60),2)+e+Y(~~t%60,2)})}function Ut(t,e){var n=(e||"").match(t);if(null===n)return null;var i=((n[n.length-1]||[])+"").match(jn)||["-",0,0],a=60*i[1]+_(i[2]);return 0===a?0:"+"===i[0]?a:-a}function qt(t,e){var i,a;return e._isUTC?(i=e.clone(),a=(b(t)||l(t)?t.valueOf():Nt(t).valueOf())-i.valueOf(),i._d.setTime(i._d.valueOf()+a),n.updateOffset(i,!1),i):Nt(t).local()}function Gt(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function Zt(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Xt(t,e){var n,i,a,r=t,o=null;return Ht(t)?r={ms:t._milliseconds,d:t._days,M:t._months}:s(t)?(r={},e?r[e]=t:r.milliseconds=t):(o=Un.exec(t))?(n="-"===o[1]?-1:1,r={y:0,d:_(o[sn])*n,h:_(o[ln])*n,m:_(o[un])*n,s:_(o[dn])*n,ms:_(Et(1e3*o[cn]))*n}):(o=qn.exec(t))?(n="-"===o[1]?-1:1,r={y:Jt(o[2],n),M:Jt(o[3],n),w:Jt(o[4],n),d:Jt(o[5],n),h:Jt(o[6],n),m:Jt(o[7],n),s:Jt(o[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(a=Qt(Nt(r.from),Nt(r.to)),(r={}).ms=a.milliseconds,r.M=a.months),i=new Vt(r),Ht(t)&&d(t,"_locale")&&(i._locale=t._locale),i}function Jt(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Kt(t,e){var n={milliseconds:0,months:0};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function Qt(t,e){var n;return t.isValid()&&e.isValid()?(e=qt(e,t),t.isBefore(e)?n=Kt(t,e):((n=Kt(e,t)).milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function $t(t,e){return function(n,i){var a,r;return null===i||isNaN(+i)||(S(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),r=n,n=i,i=r),n="string"==typeof n?+n:n,a=Xt(n,i),te(this,a,t),this}}function te(t,e,i,a){var r=e._milliseconds,o=Et(e._days),s=Et(e._months);t.isValid()&&(a=null==a||a,r&&t._d.setTime(t._d.valueOf()+r*i),o&&W(t,"Date",L(t,"Date")+o*i),s&&Q(t,L(t,"Month")+s*i),a&&n.updateOffset(t,o||s))}function ee(t,e){var n,i=12*(e.year()-t.year())+(e.month()-t.month()),a=t.clone().add(i,"months");return n=e-a<0?(e-a)/(a-t.clone().add(i-1,"months")):(e-a)/(t.clone().add(i+1,"months")-a),-(i+n)||0}function ne(t){var e;return void 0===t?this._locale._abbr:(null!=(e=_t(t))&&(this._locale=e),this)}function ie(){return this._locale}function ae(t,e){N(0,[t,t.length],0,e)}function re(t,e,n,i,a){var r;return null==t?st(this,i,a).year:(r=lt(t,i,a),e>r&&(e=r),oe.call(this,t,e,n,i,a))}function oe(t,e,n,i,a){var r=ot(t,e,n,i,a),o=at(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}function se(t){return t}function le(t,e,n,i){var a=_t(),r=h().set(i,e);return a[n](r,t)}function ue(t,e,n){if(s(t)&&(e=t,t=void 0),t=t||"",null!=e)return le(t,e,n,"month");var i,a=[];for(i=0;i<12;i++)a[i]=le(t,i,n,"month");return a}function de(t,e,n,i){"boolean"==typeof t?(s(e)&&(n=e,e=void 0),e=e||""):(n=e=t,t=!1,s(e)&&(n=e,e=void 0),e=e||"");var a=_t(),r=t?a._week.dow:0;if(null!=n)return le(e,(n+r)%7,i,"day");var o,l=[];for(o=0;o<7;o++)l[o]=le(e,(o+r)%7,i,"day");return l}function ce(t,e,n,i){var a=Xt(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function he(t){return t<0?Math.floor(t):Math.ceil(t)}function fe(t){return 4800*t/146097}function ge(t){return 146097*t/4800}function me(t){return function(){return this.as(t)}}function pe(t){return function(){return this.isValid()?this._data[t]:NaN}}function ve(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}function ye(t,e,n){var i=Xt(t).abs(),a=bi(i.as("s")),r=bi(i.as("m")),o=bi(i.as("h")),s=bi(i.as("d")),l=bi(i.as("M")),u=bi(i.as("y")),d=a<=xi.ss&&["s",a]||a<xi.s&&["ss",a]||r<=1&&["m"]||r<xi.m&&["mm",r]||o<=1&&["h"]||o<xi.h&&["hh",o]||s<=1&&["d"]||s<xi.d&&["dd",s]||l<=1&&["M"]||l<xi.M&&["MM",l]||u<=1&&["y"]||["yy",u];return d[2]=e,d[3]=+t>0,d[4]=n,ve.apply(null,d)}function be(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n,i=_i(this._milliseconds)/1e3,a=_i(this._days),r=_i(this._months);e=x((t=x(i/60))/60),i%=60,t%=60;var o=n=x(r/12),s=r%=12,l=a,u=e,d=t,c=i,h=this.asSeconds();return h?(h<0?"-":"")+"P"+(o?o+"Y":"")+(s?s+"M":"")+(l?l+"D":"")+(u||d||c?"T":"")+(u?u+"H":"")+(d?d+"M":"")+(c?c+"S":""):"P0D"}var xe,_e,ke=_e=Array.prototype.some?Array.prototype.some:function(t){for(var e=Object(this),n=e.length>>>0,i=0;i<n;i++)if(i in e&&t.call(this,e[i],i,e))return!0;return!1},we=n.momentProperties=[],Me=!1,Se={};n.suppressDeprecationWarnings=!1,n.deprecationHandler=null;var De,Ce,Pe=De=Object.keys?Object.keys:function(t){var e,n=[];for(e in t)d(t,e)&&n.push(e);return n},Te={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Ie={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Ae=/\d{1,2}/,Oe={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Fe={},Re={},Le=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,We=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Ye={},Ne={},ze=/\d/,Be=/\d\d/,Ve=/\d{3}/,He=/\d{4}/,Ee=/[+-]?\d{6}/,je=/\d\d?/,Ue=/\d\d\d\d?/,qe=/\d\d\d\d\d\d?/,Ge=/\d{1,3}/,Ze=/\d{1,4}/,Xe=/[+-]?\d{1,6}/,Je=/\d+/,Ke=/[+-]?\d+/,Qe=/Z|[+-]\d\d:?\d\d/gi,$e=/Z|[+-]\d\d(?::?\d\d)?/gi,tn=/[+-]?\d+(\.\d{1,3})?/,en=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,nn={},an={},rn=0,on=1,sn=2,ln=3,un=4,dn=5,cn=6,hn=7,fn=8,gn=Ce=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e<this.length;++e)if(this[e]===t)return e;return-1};N("M",["MM",2],"Mo",function(){return this.month()+1}),N("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),N("MMMM",0,0,function(t){return this.localeData().months(this,t)}),T("month","M"),O("month",8),E("M",je),E("MM",je,Be),E("MMM",function(t,e){return e.monthsShortRegex(t)}),E("MMMM",function(t,e){return e.monthsRegex(t)}),G(["M","MM"],function(t,e){e[on]=_(t)-1}),G(["MMM","MMMM"],function(t,e,n,i){var a=n._locale.monthsParse(t,i,n._strict);null!=a?e[on]=a:g(n).invalidMonth=t});var mn=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,pn="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),vn="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),yn=en,bn=en;N("Y",0,0,function(){var t=this.year();return t<=9999?""+t:"+"+t}),N(0,["YY",2],0,function(){return this.year()%100}),N(0,["YYYY",4],0,"year"),N(0,["YYYYY",5],0,"year"),N(0,["YYYYYY",6,!0],0,"year"),T("year","y"),O("year",1),E("Y",Ke),E("YY",je,Be),E("YYYY",Ze,He),E("YYYYY",Xe,Ee),E("YYYYYY",Xe,Ee),G(["YYYYY","YYYYYY"],rn),G("YYYY",function(t,e){e[rn]=2===t.length?n.parseTwoDigitYear(t):_(t)}),G("YY",function(t,e){e[rn]=n.parseTwoDigitYear(t)}),G("Y",function(t,e){e[rn]=parseInt(t,10)}),n.parseTwoDigitYear=function(t){return _(t)+(_(t)>68?1900:2e3)};var xn=R("FullYear",!0);N("w",["ww",2],"wo","week"),N("W",["WW",2],"Wo","isoWeek"),T("week","w"),T("isoWeek","W"),O("week",5),O("isoWeek",5),E("w",je),E("ww",je,Be),E("W",je),E("WW",je,Be),Z(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=_(t)});var _n={dow:0,doy:6};N("d",0,"do","day"),N("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),N("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),N("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),N("e",0,0,"weekday"),N("E",0,0,"isoWeekday"),T("day","d"),T("weekday","e"),T("isoWeekday","E"),O("day",11),O("weekday",11),O("isoWeekday",11),E("d",je),E("e",je),E("E",je),E("dd",function(t,e){return e.weekdaysMinRegex(t)}),E("ddd",function(t,e){return e.weekdaysShortRegex(t)}),E("dddd",function(t,e){return e.weekdaysRegex(t)}),Z(["dd","ddd","dddd"],function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:g(n).invalidWeekday=t}),Z(["d","e","E"],function(t,e,n,i){e[i]=_(t)});var kn="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),wn="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Mn="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Sn=en,Dn=en,Cn=en;N("H",["HH",2],0,"hour"),N("h",["hh",2],0,ft),N("k",["kk",2],0,function(){return this.hours()||24}),N("hmm",0,0,function(){return""+ft.apply(this)+Y(this.minutes(),2)}),N("hmmss",0,0,function(){return""+ft.apply(this)+Y(this.minutes(),2)+Y(this.seconds(),2)}),N("Hmm",0,0,function(){return""+this.hours()+Y(this.minutes(),2)}),N("Hmmss",0,0,function(){return""+this.hours()+Y(this.minutes(),2)+Y(this.seconds(),2)}),gt("a",!0),gt("A",!1),T("hour","h"),O("hour",13),E("a",mt),E("A",mt),E("H",je),E("h",je),E("k",je),E("HH",je,Be),E("hh",je,Be),E("kk",je,Be),E("hmm",Ue),E("hmmss",qe),E("Hmm",Ue),E("Hmmss",qe),G(["H","HH"],ln),G(["k","kk"],function(t,e,n){var i=_(t);e[ln]=24===i?0:i}),G(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),G(["h","hh"],function(t,e,n){e[ln]=_(t),g(n).bigHour=!0}),G("hmm",function(t,e,n){var i=t.length-2;e[ln]=_(t.substr(0,i)),e[un]=_(t.substr(i)),g(n).bigHour=!0}),G("hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[ln]=_(t.substr(0,i)),e[un]=_(t.substr(i,2)),e[dn]=_(t.substr(a)),g(n).bigHour=!0}),G("Hmm",function(t,e,n){var i=t.length-2;e[ln]=_(t.substr(0,i)),e[un]=_(t.substr(i))}),G("Hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[ln]=_(t.substr(0,i)),e[un]=_(t.substr(i,2)),e[dn]=_(t.substr(a))});var Pn,Tn=/[ap]\.?m?\.?/i,In=R("Hours",!0),An={calendar:Te,longDateFormat:Ie,invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:Ae,relativeTime:Oe,months:pn,monthsShort:vn,week:_n,weekdays:kn,weekdaysMin:Mn,weekdaysShort:wn,meridiemParse:Tn},On={},Fn={},Rn=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ln=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Wn=/Z|[+-]\d\d(?::?\d\d)?/,Yn=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Nn=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],zn=/^\/?Date\((\-?\d+)/i,Bn=/^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;n.createFromInputFallback=M("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),n.ISO_8601=function(){},n.RFC_2822=function(){};var Vn=M("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=Nt.apply(null,arguments);return this.isValid()&&t.isValid()?t<this?this:t:p()}),Hn=M("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=Nt.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:p()}),En=["year","quarter","month","week","day","hour","minute","second","millisecond"];jt("Z",":"),jt("ZZ",""),E("Z",$e),E("ZZ",$e),G(["Z","ZZ"],function(t,e,n){n._useUTC=!0,n._tzm=Ut($e,t)});var jn=/([\+\-]|\d\d)/gi;n.updateOffset=function(){};var Un=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,qn=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Xt.fn=Vt.prototype,Xt.invalid=function(){return Xt(NaN)};var Gn=$t(1,"add"),Zn=$t(-1,"subtract");n.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",n.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xn=M("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});N(0,["gg",2],0,function(){return this.weekYear()%100}),N(0,["GG",2],0,function(){return this.isoWeekYear()%100}),ae("gggg","weekYear"),ae("ggggg","weekYear"),ae("GGGG","isoWeekYear"),ae("GGGGG","isoWeekYear"),T("weekYear","gg"),T("isoWeekYear","GG"),O("weekYear",1),O("isoWeekYear",1),E("G",Ke),E("g",Ke),E("GG",je,Be),E("gg",je,Be),E("GGGG",Ze,He),E("gggg",Ze,He),E("GGGGG",Xe,Ee),E("ggggg",Xe,Ee),Z(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=_(t)}),Z(["gg","GG"],function(t,e,i,a){e[a]=n.parseTwoDigitYear(t)}),N("Q",0,"Qo","quarter"),T("quarter","Q"),O("quarter",7),E("Q",ze),G("Q",function(t,e){e[on]=3*(_(t)-1)}),N("D",["DD",2],"Do","date"),T("date","D"),O("date",9),E("D",je),E("DD",je,Be),E("Do",function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient}),G(["D","DD"],sn),G("Do",function(t,e){e[sn]=_(t.match(je)[0],10)});var Jn=R("Date",!0);N("DDD",["DDDD",3],"DDDo","dayOfYear"),T("dayOfYear","DDD"),O("dayOfYear",4),E("DDD",Ge),E("DDDD",Ve),G(["DDD","DDDD"],function(t,e,n){n._dayOfYear=_(t)}),N("m",["mm",2],0,"minute"),T("minute","m"),O("minute",14),E("m",je),E("mm",je,Be),G(["m","mm"],un);var Kn=R("Minutes",!1);N("s",["ss",2],0,"second"),T("second","s"),O("second",15),E("s",je),E("ss",je,Be),G(["s","ss"],dn);var Qn=R("Seconds",!1);N("S",0,0,function(){return~~(this.millisecond()/100)}),N(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),N(0,["SSS",3],0,"millisecond"),N(0,["SSSS",4],0,function(){return 10*this.millisecond()}),N(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),N(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),N(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),N(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),N(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),T("millisecond","ms"),O("millisecond",16),E("S",Ge,ze),E("SS",Ge,Be),E("SSS",Ge,Ve);var $n;for($n="SSSS";$n.length<=9;$n+="S")E($n,Je);for($n="S";$n.length<=9;$n+="S")G($n,function(t,e){e[cn]=_(1e3*("0."+t))});var ti=R("Milliseconds",!1);N("z",0,0,"zoneAbbr"),N("zz",0,0,"zoneName");var ei=y.prototype;ei.add=Gn,ei.calendar=function(t,e){var i=t||Nt(),a=qt(i,this).startOf("day"),r=n.calendarFormat(this,a)||"sameElse",o=e&&(D(e[r])?e[r].call(this,i):e[r]);return this.format(o||this.localeData().calendar(r,this,Nt(i)))},ei.clone=function(){return new y(this)},ei.diff=function(t,e,n){var i,a,r,o;return this.isValid()&&(i=qt(t,this)).isValid()?(a=6e4*(i.utcOffset()-this.utcOffset()),"year"===(e=I(e))||"month"===e||"quarter"===e?(o=ee(this,i),"quarter"===e?o/=3:"year"===e&&(o/=12)):(r=this-i,o="second"===e?r/1e3:"minute"===e?r/6e4:"hour"===e?r/36e5:"day"===e?(r-a)/864e5:"week"===e?(r-a)/6048e5:r),n?o:x(o)):NaN},ei.endOf=function(t){return void 0===(t=I(t))||"millisecond"===t?this:("date"===t&&(t="day"),this.startOf(t).add(1,"isoWeek"===t?"week":t).subtract(1,"ms"))},ei.format=function(t){t||(t=this.isUtc()?n.defaultFormatUtc:n.defaultFormat);var e=V(this,t);return this.localeData().postformat(e)},ei.from=function(t,e){return this.isValid()&&(b(t)&&t.isValid()||Nt(t).isValid())?Xt({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},ei.fromNow=function(t){return this.from(Nt(),t)},ei.to=function(t,e){return this.isValid()&&(b(t)&&t.isValid()||Nt(t).isValid())?Xt({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},ei.toNow=function(t){return this.to(Nt(),t)},ei.get=function(t){return t=I(t),D(this[t])?this[t]():this},ei.invalidAt=function(){return g(this).overflow},ei.isAfter=function(t,e){var n=b(t)?t:Nt(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=I(o(e)?"millisecond":e))?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(e).valueOf())},ei.isBefore=function(t,e){var n=b(t)?t:Nt(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=I(o(e)?"millisecond":e))?this.valueOf()<n.valueOf():this.clone().endOf(e).valueOf()<n.valueOf())},ei.isBetween=function(t,e,n,i){return("("===(i=i||"()")[0]?this.isAfter(t,n):!this.isBefore(t,n))&&(")"===i[1]?this.isBefore(e,n):!this.isAfter(e,n))},ei.isSame=function(t,e){var n,i=b(t)?t:Nt(t);return!(!this.isValid()||!i.isValid())&&("millisecond"===(e=I(e||"millisecond"))?this.valueOf()===i.valueOf():(n=i.valueOf(),this.clone().startOf(e).valueOf()<=n&&n<=this.clone().endOf(e).valueOf()))},ei.isSameOrAfter=function(t,e){return this.isSame(t,e)||this.isAfter(t,e)},ei.isSameOrBefore=function(t,e){return this.isSame(t,e)||this.isBefore(t,e)},ei.isValid=function(){return m(this)},ei.lang=Xn,ei.locale=ne,ei.localeData=ie,ei.max=Hn,ei.min=Vn,ei.parsingFlags=function(){return c({},g(this))},ei.set=function(t,e){if("object"==typeof t)for(var n=F(t=A(t)),i=0;i<n.length;i++)this[n[i].unit](t[n[i].unit]);else if(t=I(t),D(this[t]))return this[t](e);return this},ei.startOf=function(t){switch(t=I(t)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===t&&this.weekday(0),"isoWeek"===t&&this.isoWeekday(1),"quarter"===t&&this.month(3*Math.floor(this.month()/3)),this},ei.subtract=Zn,ei.toArray=function(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]},ei.toObject=function(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}},ei.toDate=function(){return new Date(this.valueOf())},ei.toISOString=function(){if(!this.isValid())return null;var t=this.clone().utc();return t.year()<0||t.year()>9999?V(t,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):D(Date.prototype.toISOString)?this.toDate().toISOString():V(t,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},ei.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a=e+'[")]';return this.format(n+i+"-MM-DD[T]HH:mm:ss.SSS"+a)},ei.toJSON=function(){return this.isValid()?this.toISOString():null},ei.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},ei.unix=function(){return Math.floor(this.valueOf()/1e3)},ei.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},ei.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},ei.year=xn,ei.isLeapYear=function(){return nt(this.year())},ei.weekYear=function(t){return re.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},ei.isoWeekYear=function(t){return re.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},ei.quarter=ei.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},ei.month=$,ei.daysInMonth=function(){return J(this.year(),this.month())},ei.week=ei.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},ei.isoWeek=ei.isoWeeks=function(t){var e=st(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},ei.weeksInYear=function(){var t=this.localeData()._week;return lt(this.year(),t.dow,t.doy)},ei.isoWeeksInYear=function(){return lt(this.year(),1,4)},ei.date=Jn,ei.day=ei.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=ut(t,this.localeData()),this.add(t-e,"d")):e},ei.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},ei.isoWeekday=function(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=dt(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7},ei.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},ei.hour=ei.hours=In,ei.minute=ei.minutes=Kn,ei.second=ei.seconds=Qn,ei.millisecond=ei.milliseconds=ti,ei.utcOffset=function(t,e,i){var a,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=Ut($e,t)))return this}else Math.abs(t)<16&&!i&&(t*=60);return!this._isUTC&&e&&(a=Gt(this)),this._offset=t,this._isUTC=!0,null!=a&&this.add(a,"m"),r!==t&&(!e||this._changeInProgress?te(this,Xt(t-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,n.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Gt(this)},ei.utc=function(t){return this.utcOffset(0,t)},ei.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Gt(this),"m")),this},ei.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=Ut(Qe,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this},ei.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Nt(t).utcOffset():0,(this.utcOffset()-t)%60==0)},ei.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},ei.isLocal=function(){return!!this.isValid()&&!this._isUTC},ei.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},ei.isUtc=Zt,ei.isUTC=Zt,ei.zoneAbbr=function(){return this._isUTC?"UTC":""},ei.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},ei.dates=M("dates accessor is deprecated. Use date instead.",Jn),ei.months=M("months accessor is deprecated. Use month instead",$),ei.years=M("years accessor is deprecated. Use year instead",xn),ei.zone=M("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}),ei.isDSTShifted=M("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var t={};if(v(t,this),(t=Lt(t))._a){var e=t._isUTC?h(t._a):Nt(t._a);this._isDSTShifted=this.isValid()&&k(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted});var ni=P.prototype;ni.calendar=function(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return D(i)?i.call(e,n):i},ni.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])},ni.invalidDate=function(){return this._invalidDate},ni.ordinal=function(t){return this._ordinal.replace("%d",t)},ni.preparse=se,ni.postformat=se,ni.relativeTime=function(t,e,n,i){var a=this._relativeTime[n];return D(a)?a(t,e,n,i):a.replace(/%d/i,t)},ni.pastFuture=function(t,e){var n=this._relativeTime[t>0?"future":"past"];return D(n)?n(e):n.replace(/%s/i,e)},ni.set=function(t){var e,n;for(n in t)D(e=t[n])?this[n]=e:this["_"+n]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},ni.months=function(t,e){return t?i(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||mn).test(e)?"format":"standalone"][t.month()]:i(this._months)?this._months:this._months.standalone},ni.monthsShort=function(t,e){return t?i(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[mn.test(e)?"format":"standalone"][t.month()]:i(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},ni.monthsParse=function(t,e,n){var i,a,r;if(this._monthsParseExact)return K.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(a=h([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}},ni.monthsRegex=function(t){return this._monthsParseExact?(d(this,"_monthsRegex")||tt.call(this),t?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=bn),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},ni.monthsShortRegex=function(t){return this._monthsParseExact?(d(this,"_monthsRegex")||tt.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=yn),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},ni.week=function(t){return st(t,this._week.dow,this._week.doy).week},ni.firstDayOfYear=function(){return this._week.doy},ni.firstDayOfWeek=function(){return this._week.dow},ni.weekdays=function(t,e){return t?i(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(e)?"format":"standalone"][t.day()]:i(this._weekdays)?this._weekdays:this._weekdays.standalone},ni.weekdaysMin=function(t){return t?this._weekdaysMin[t.day()]:this._weekdaysMin},ni.weekdaysShort=function(t){return t?this._weekdaysShort[t.day()]:this._weekdaysShort},ni.weekdaysParse=function(t,e,n){var i,a,r;if(this._weekdaysParseExact)return ct.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(a=h([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".",".?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}},ni.weekdaysRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ht.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=Sn),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},ni.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ht.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Dn),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},ni.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ht.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Cn),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},ni.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},ni.meridiem=function(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"},bt("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===_(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),n.lang=M("moment.lang is deprecated. Use moment.locale instead.",bt),n.langData=M("moment.langData is deprecated. Use moment.localeData instead.",_t);var ii=Math.abs,ai=me("ms"),ri=me("s"),oi=me("m"),si=me("h"),li=me("d"),ui=me("w"),di=me("M"),ci=me("y"),hi=pe("milliseconds"),fi=pe("seconds"),gi=pe("minutes"),mi=pe("hours"),pi=pe("days"),vi=pe("months"),yi=pe("years"),bi=Math.round,xi={ss:44,s:45,m:45,h:22,d:26,M:11},_i=Math.abs,ki=Vt.prototype;return ki.isValid=function(){return this._isValid},ki.abs=function(){var t=this._data;return this._milliseconds=ii(this._milliseconds),this._days=ii(this._days),this._months=ii(this._months),t.milliseconds=ii(t.milliseconds),t.seconds=ii(t.seconds),t.minutes=ii(t.minutes),t.hours=ii(t.hours),t.months=ii(t.months),t.years=ii(t.years),this},ki.add=function(t,e){return ce(this,t,e,1)},ki.subtract=function(t,e){return ce(this,t,e,-1)},ki.as=function(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=I(t))||"year"===t)return e=this._days+i/864e5,n=this._months+fe(e),"month"===t?n:n/12;switch(e=this._days+Math.round(ge(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}},ki.asMilliseconds=ai,ki.asSeconds=ri,ki.asMinutes=oi,ki.asHours=si,ki.asDays=li,ki.asWeeks=ui,ki.asMonths=di,ki.asYears=ci,ki.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*_(this._months/12):NaN},ki._bubble=function(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||r<=0&&o<=0&&s<=0||(r+=864e5*he(ge(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=x(r/1e3),l.seconds=t%60,e=x(t/60),l.minutes=e%60,n=x(e/60),l.hours=n%24,o+=x(n/24),a=x(fe(o)),s+=a,o-=he(ge(a)),i=x(s/12),s%=12,l.days=o,l.months=s,l.years=i,this},ki.get=function(t){return t=I(t),this.isValid()?this[t+"s"]():NaN},ki.milliseconds=hi,ki.seconds=fi,ki.minutes=gi,ki.hours=mi,ki.days=pi,ki.weeks=function(){return x(this.days()/7)},ki.months=vi,ki.years=yi,ki.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=ye(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)},ki.toISOString=be,ki.toString=be,ki.toJSON=be,ki.locale=ne,ki.localeData=ie,ki.toIsoString=M("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",be),ki.lang=Xn,N("X",0,0,"unix"),N("x",0,0,"valueOf"),E("x",Ke),E("X",tn),G("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),G("x",function(t,e,n){n._d=new Date(_(t))}),n.version="2.18.1",function(t){xe=t}(Nt),n.fn=ei,n.min=function(){return zt("isBefore",[].slice.call(arguments,0))},n.max=function(){return zt("isAfter",[].slice.call(arguments,0))},n.now=function(){return Date.now?Date.now():+new Date},n.utc=h,n.unix=function(t){return Nt(1e3*t)},n.months=function(t,e){return ue(t,e,"months")},n.isDate=l,n.locale=bt,n.invalid=p,n.duration=Xt,n.isMoment=b,n.weekdays=function(t,e,n){return de(t,e,n,"weekdays")},n.parseZone=function(){return Nt.apply(null,arguments).parseZone()},n.localeData=_t,n.isDuration=Ht,n.monthsShort=function(t,e){return ue(t,e,"monthsShort")},n.weekdaysMin=function(t,e,n){return de(t,e,n,"weekdaysMin")},n.defineLocale=xt,n.updateLocale=function(t,e){if(null!=e){var n,i=An;null!=On[t]&&(i=On[t]._config),(n=new P(e=C(i,e))).parentLocale=On[t],On[t]=n,bt(t)}else null!=On[t]&&(null!=On[t].parentLocale?On[t]=On[t].parentLocale:null!=On[t]&&delete On[t]);return On[t]},n.locales=function(){return Pe(On)},n.weekdaysShort=function(t,e,n){return de(t,e,n,"weekdaysShort")},n.normalizeUnits=I,n.relativeTimeRounding=function(t){return void 0===t?bi:"function"==typeof t&&(bi=t,!0)},n.relativeTimeThreshold=function(t,e){return void 0!==xi[t]&&(void 0===e?xi[t]:(xi[t]=e,"s"===t&&(xi.ss=e-1),!0))},n.calendarFormat=function(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},n.prototype=ei,n})},{}],7:[function(t,e,n){var i=t(29)();i.helpers=t(45),t(27)(i),i.defaults=t(25),i.Element=t(26),i.elements=t(40),i.Interaction=t(28),i.platform=t(48),t(31)(i),t(22)(i),t(23)(i),t(24)(i),t(30)(i),t(33)(i),t(32)(i),t(35)(i),t(54)(i),t(52)(i),t(53)(i),t(55)(i),t(56)(i),t(57)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(21)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i);var a=[];a.push(t(49)(i),t(50)(i),t(51)(i)),i.plugins.register(a),i.platform.initialize(),e.exports=i,"undefined"!=typeof window&&(window.Chart=i),i.canvasHelpers=i.helpers.canvas},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,35:35,40:40,45:45,48:48,49:49,50:50,51:51,52:52,53:53,54:54,55:55,56:56,57:57,8:8,9:9}],8:[function(t,e,n){"use strict";e.exports=function(t){t.Bar=function(e,n){return n.type="bar",new t(e,n)}}},{}],9:[function(t,e,n){"use strict";e.exports=function(t){t.Bubble=function(e,n){return n.type="bubble",new t(e,n)}}},{}],10:[function(t,e,n){"use strict";e.exports=function(t){t.Doughnut=function(e,n){return n.type="doughnut",new t(e,n)}}},{}],11:[function(t,e,n){"use strict";e.exports=function(t){t.Line=function(e,n){return n.type="line",new t(e,n)}}},{}],12:[function(t,e,n){"use strict";e.exports=function(t){t.PolarArea=function(e,n){return n.type="polarArea",new t(e,n)}}},{}],13:[function(t,e,n){"use strict";e.exports=function(t){t.Radar=function(e,n){return n.type="radar",new t(e,n)}}},{}],14:[function(t,e,n){"use strict";e.exports=function(t){t.Scatter=function(e,n){return n.type="scatter",new t(e,n)}}},{}],15:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),i._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var n="";return t.length>0&&(t[0].yLabel?n=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(n=e.labels[t[0].index])),n},label:function(t,e){return(e.datasets[t.datasetIndex].label||"")+": "+t.xLabel}},mode:"index",axis:"y"}}),e.exports=function(t){t.controllers.bar=t.DatasetController.extend({dataElementType:a.Rectangle,initialize:function(){var e,n=this;t.DatasetController.prototype.initialize.apply(n,arguments),(e=n.getMeta()).stack=n.getDataset().stack,e.bar=!0},update:function(t){var e,n,i=this,a=i.getMeta().data;for(i._ruler=i.getRuler(),e=0,n=a.length;e<n;++e)i.updateElement(a[e],e,t)},updateElement:function(t,e,n){var i=this,a=i.chart,o=i.getMeta(),s=i.getDataset(),l=t.custom||{},u=a.options.elements.rectangle;t._xScale=i.getScaleForId(o.xAxisID),t._yScale=i.getScaleForId(o.yAxisID),t._datasetIndex=i.index,t._index=e,t._model={datasetLabel:s.label,label:a.data.labels[e],borderSkipped:l.borderSkipped?l.borderSkipped:u.borderSkipped,backgroundColor:l.backgroundColor?l.backgroundColor:r.valueAtIndexOrDefault(s.backgroundColor,e,u.backgroundColor),borderColor:l.borderColor?l.borderColor:r.valueAtIndexOrDefault(s.borderColor,e,u.borderColor),borderWidth:l.borderWidth?l.borderWidth:r.valueAtIndexOrDefault(s.borderWidth,e,u.borderWidth)},i.updateElementGeometry(t,e,n),t.pivot()},updateElementGeometry:function(t,e,n){var i=this,a=t._model,r=i.getValueScale(),o=r.getBasePixel(),s=r.isHorizontal(),l=i._ruler||i.getRuler(),u=i.calculateBarValuePixels(i.index,e),d=i.calculateBarIndexPixels(i.index,e,l);a.horizontal=s,a.base=n?o:u.base,a.x=s?n?o:u.head:d.center,a.y=s?d.center:n?o:u.head,a.height=s?d.size:void 0,a.width=s?void 0:d.size},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())},getStackCount:function(t){var e,n,i=this,a=i.chart,r=i.getIndexScale().options.stacked,o=void 0===t?a.data.datasets.length:t+1,s=[];for(e=0;e<o;++e)(n=a.getDatasetMeta(e)).bar&&a.isDatasetVisible(e)&&(!1===r||!0===r&&-1===s.indexOf(n.stack)||void 0===r&&(void 0===n.stack||-1===s.indexOf(n.stack)))&&s.push(n.stack);return s.length},getStackIndex:function(t){return this.getStackCount(t)-1},getRuler:function(){var t,e,n=this,i=n.getIndexScale(),a=n.getStackCount(),r=n.index,o=[],s=i.isHorizontal(),l=s?i.left:i.top,u=l+(s?i.width:i.height);for(t=0,e=n.getMeta().data.length;t<e;++t)o.push(i.getPixelForValue(null,t,r));return{pixels:o,start:l,end:u,stackCount:a,scale:i}},calculateBarValuePixels:function(t,e){var n,i,a,r,o,s,l=this,u=l.chart,d=l.getMeta(),c=l.getValueScale(),h=u.data.datasets,f=c.getRightValue(h[t].data[e]),g=c.options.stacked,m=d.stack,p=0;if(g||void 0===g&&void 0!==m)for(n=0;n<t;++n)(i=u.getDatasetMeta(n)).bar&&i.stack===m&&i.controller.getValueScaleId()===c.id&&u.isDatasetVisible(n)&&(a=c.getRightValue(h[n].data[e]),(f<0&&a<0||f>=0&&a>0)&&(p+=a));return r=c.getPixelForValue(p),o=c.getPixelForValue(p+f),s=(o-r)/2,{size:s,base:r,head:o,center:o+s/2}},calculateBarIndexPixels:function(t,e,n){var i,a,o,s,l,u,d=this,c=n.scale.options,h=d.getStackIndex(t),f=n.pixels,g=f[e],m=f.length,p=n.start,v=n.end;return 1===m?(i=g>p?g-p:v-g,a=g<v?v-g:g-p):(e>0&&(i=(g-f[e-1])/2,e===m-1&&(a=i)),e<m-1&&(a=(f[e+1]-g)/2,0===e&&(i=a))),o=i*c.categoryPercentage,s=a*c.categoryPercentage,l=(o+s)/n.stackCount,u=l*c.barPercentage,u=Math.min(r.valueOrDefault(c.barThickness,u),r.valueOrDefault(c.maxBarThickness,1/0)),g-=o,g+=l*h,g+=(l-u)/2,{size:u,base:g,head:g+u,center:g+u/2}},draw:function(){var t=this,e=t.chart,n=t.getValueScale(),i=t.getMeta().data,a=t.getDataset(),o=i.length,s=0;for(r.canvas.clipArea(e.ctx,e.chartArea);s<o;++s)isNaN(n.getRightValue(a.data[s]))||i[s].draw();r.canvas.unclipArea(e.ctx)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model;a.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:r.valueAtIndexOrDefault(e.hoverBackgroundColor,n,r.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor?i.hoverBorderColor:r.valueAtIndexOrDefault(e.hoverBorderColor,n,r.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:r.valueAtIndexOrDefault(e.hoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model,o=this.chart.options.elements.rectangle;a.backgroundColor=i.backgroundColor?i.backgroundColor:r.valueAtIndexOrDefault(e.backgroundColor,n,o.backgroundColor),a.borderColor=i.borderColor?i.borderColor:r.valueAtIndexOrDefault(e.borderColor,n,o.borderColor),a.borderWidth=i.borderWidth?i.borderWidth:r.valueAtIndexOrDefault(e.borderWidth,n,o.borderWidth)}}),t.controllers.horizontalBar=t.controllers.bar.extend({getValueScaleId:function(){return this.getMeta().xAxisID},getIndexScaleId:function(){return this.getMeta().yAxisID}})}},{25:25,40:40,45:45}],16:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._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+")"}}}}),e.exports=function(t){t.controllers.bubble=t.DatasetController.extend({dataElementType:a.Point,update:function(t){var e=this,n=e.getMeta().data;r.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._resolveElementOptions(t,e),u=i.getDataset().data[e],d=i.index,c=n?o.getPixelForDecimal(.5):o.getPixelForValue("object"==typeof u?u:NaN,e,d),h=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,radius:n?0:l.radius,skip:r.skip||isNaN(c)||isNaN(h),x:c,y:h},t.pivot()},setHoverStyle:function(t){var e=t._model,n=t._options;e.backgroundColor=r.valueOrDefault(n.hoverBackgroundColor,r.getHoverColor(n.backgroundColor)),e.borderColor=r.valueOrDefault(n.hoverBorderColor,r.getHoverColor(n.borderColor)),e.borderWidth=r.valueOrDefault(n.hoverBorderWidth,n.borderWidth),e.radius=n.radius+n.hoverRadius},removeHoverStyle:function(t){var e=t._model,n=t._options;e.backgroundColor=n.backgroundColor,e.borderColor=n.borderColor,e.borderWidth=n.borderWidth,e.radius=n.radius},_resolveElementOptions:function(t,e){var n,i,a,o=this,s=o.chart,l=s.data.datasets[o.index],u=t.custom||{},d=s.options.elements.point,c=r.options.resolve,h=l.data[e],f={},g={chart:s,dataIndex:e,dataset:l,datasetIndex:o.index},m=["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle"];for(n=0,i=m.length;n<i;++n)f[a=m[n]]=c([u[a],l[a],d[a]],g,e);return f.radius=c([u.radius,h?h.r:void 0,l.radius,d.radius],g,e),f}})}},{25:25,40:40,45:45}],17:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},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),o=e.datasets[0],s=a.data[i],l=s&&s.custom||{},u=r.valueAtIndexOrDefault,d=t.options.elements.arc;return{text:n,fillStyle:l.backgroundColor?l.backgroundColor:u(o.backgroundColor,i,d.backgroundColor),strokeStyle:l.borderColor?l.borderColor:u(o.borderColor,i,d.borderColor),lineWidth:l.borderWidth?l.borderWidth:u(o.borderWidth,i,d.borderWidth),hidden:isNaN(o.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:-.5*Math.PI,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.labels[t.index],i=": "+e.datasets[t.datasetIndex].data[t.index];return r.isArray(n)?(n=n.slice())[0]+=i:n+=i,n}}}}),i._set("pie",r.clone(i.doughnut)),i._set("pie",{cutoutPercentage:0}),e.exports=function(t){t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:a.Arc,linkScales:r.noop,getRingIndex:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var e=this,n=e.chart,i=n.chartArea,a=n.options,o=a.elements.arc,s=i.right-i.left-o.borderWidth,l=i.bottom-i.top-o.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=e.getMeta(),h=a.cutoutPercentage,f=a.circumference;if(f<2*Math.PI){var g=a.rotation%(2*Math.PI),m=(g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0))+f,p={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(m),y:Math.sin(m)},y=g<=0&&m>=0||g<=2*Math.PI&&2*Math.PI<=m,b=g<=.5*Math.PI&&.5*Math.PI<=m||g<=2.5*Math.PI&&2.5*Math.PI<=m,x=g<=-Math.PI&&-Math.PI<=m||g<=Math.PI&&Math.PI<=m,_=g<=.5*-Math.PI&&.5*-Math.PI<=m||g<=1.5*Math.PI&&1.5*Math.PI<=m,k=h/100,w={x:x?-1:Math.min(p.x*(p.x<0?1:k),v.x*(v.x<0?1:k)),y:_?-1:Math.min(p.y*(p.y<0?1:k),v.y*(v.y<0?1:k))},M={x:y?1:Math.max(p.x*(p.x>0?1:k),v.x*(v.x>0?1:k)),y:b?1:Math.max(p.y*(p.y>0?1:k),v.y*(v.y>0?1:k))},S={width:.5*(M.x-w.x),height:.5*(M.y-w.y)};u=Math.min(s/S.width,l/S.height),d={x:-.5*(M.x+w.x),y:-.5*(M.y+w.y)}}n.borderWidth=e.getMaxBorderWidth(c.data),n.outerRadius=Math.max((u-n.borderWidth)/2,0),n.innerRadius=Math.max(h?n.outerRadius/100*h:0,0),n.radiusLength=(n.outerRadius-n.innerRadius)/n.getVisibleDatasetCount(),n.offsetX=d.x*n.outerRadius,n.offsetY=d.y*n.outerRadius,c.total=e.calculateTotal(),e.outerRadius=n.outerRadius-n.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-n.radiusLength,0),r.each(c.data,function(n,i){e.updateElement(n,i,t)})},updateElement:function(t,e,n){var i=this,a=i.chart,o=a.chartArea,s=a.options,l=s.animation,u=(o.left+o.right)/2,d=(o.top+o.bottom)/2,c=s.rotation,h=s.rotation,f=i.getDataset(),g=n&&l.animateRotate?0:t.hidden?0:i.calculateCircumference(f.data[e])*(s.circumference/(2*Math.PI)),m=n&&l.animateScale?0:i.innerRadius,p=n&&l.animateScale?0:i.outerRadius,v=r.valueAtIndexOrDefault;r.extend(t,{_datasetIndex:i.index,_index:e,_model:{x:u+a.offsetX,y:d+a.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:p,innerRadius:m,label:v(f.label,e,a.data.labels[e])}});var y=t._model;this.removeHoverStyle(t),n&&l.animateRotate||(y.startAngle=0===e?s.rotation:i.getMeta().data[e-1]._model.endAngle,y.endAngle=y.startAngle+y.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,e=this.getDataset(),n=this.getMeta(),i=0;return r.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)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,n,i=0,a=this.index,r=t.length,o=0;o<r;o++)e=t[o]._model?t[o]._model.borderWidth:0,i=(n=t[o]._chart?t[o]._chart.config.data.datasets[a].hoverBorderWidth:0)>(i=e>i?e:i)?n:i;return i}})}},{25:25,40:40,45:45}],18:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),e.exports=function(t){function e(t,e){return r.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,update:function(t){var n,i,a,o=this,s=o.getMeta(),l=s.dataset,u=s.data||[],d=o.chart.options,c=d.elements.line,h=o.getScaleForId(s.yAxisID),f=o.getDataset(),g=e(f,d);for(g&&(a=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=o.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:a.tension?a.tension:r.valueOrDefault(f.lineTension,c.tension),backgroundColor:a.backgroundColor?a.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:a.borderWidth?a.borderWidth:f.borderWidth||c.borderWidth,borderColor:a.borderColor?a.borderColor:f.borderColor||c.borderColor,borderCapStyle:a.borderCapStyle?a.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:a.borderDash?a.borderDash:f.borderDash||c.borderDash,borderDashOffset:a.borderDashOffset?a.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:a.borderJoinStyle?a.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:a.fill?a.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:a.steppedLine?a.steppedLine:r.valueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:a.cubicInterpolationMode?a.cubicInterpolationMode:r.valueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode)},l.pivot()),n=0,i=u.length;n<i;++n)o.updateElement(u[n],n,t);for(g&&0!==l._model.tension&&o.updateBezierControlPoints(),n=0,i=u.length;n<i;++n)u[n].pivot()},getPointBackgroundColor:function(t,e){var n=this.chart.options.elements.point.backgroundColor,i=this.getDataset(),a=t.custom||{};return a.backgroundColor?n=a.backgroundColor:i.pointBackgroundColor?n=r.valueAtIndexOrDefault(i.pointBackgroundColor,e,n):i.backgroundColor&&(n=i.backgroundColor),n},getPointBorderColor:function(t,e){var n=this.chart.options.elements.point.borderColor,i=this.getDataset(),a=t.custom||{};return a.borderColor?n=a.borderColor:i.pointBorderColor?n=r.valueAtIndexOrDefault(i.pointBorderColor,e,n):i.borderColor&&(n=i.borderColor),n},getPointBorderWidth:function(t,e){var n=this.chart.options.elements.point.borderWidth,i=this.getDataset(),a=t.custom||{};return isNaN(a.borderWidth)?!isNaN(i.pointBorderWidth)||r.isArray(i.pointBorderWidth)?n=r.valueAtIndexOrDefault(i.pointBorderWidth,e,n):isNaN(i.borderWidth)||(n=i.borderWidth):n=a.borderWidth,n},updateElement:function(t,e,n){var i,a,o=this,s=o.getMeta(),l=t.custom||{},u=o.getDataset(),d=o.index,c=u.data[e],h=o.getScaleForId(s.yAxisID),f=o.getScaleForId(s.xAxisID),g=o.chart.options.elements.point;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),i=f.getPixelForValue("object"==typeof c?c:NaN,e,d),a=n?h.getBasePixel():o.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:i,y:a,skip:l.skip||isNaN(i)||isNaN(a),radius:l.radius||r.valueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||r.valueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:o.getPointBackgroundColor(t,e),borderColor:o.getPointBorderColor(t,e),borderWidth:o.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,steppedLine:!!s.dataset._model&&s.dataset._model.steppedLine,hitRadius:l.hitRadius||r.valueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,n){var i,a,r,o=this,s=o.chart,l=o.getMeta(),u=o.getScaleForId(l.yAxisID),d=0,c=0;if(u.options.stacked){for(i=0;i<n;i++)if(a=s.data.datasets[i],"line"===(r=s.getDatasetMeta(i)).type&&r.yAxisID===u.id&&s.isDatasetVisible(i)){var h=Number(u.getRightValue(a.data[e]));h<0?c+=h||0:d+=h||0}var f=Number(u.getRightValue(t));return f<0?u.getPixelForValue(c+f):u.getPixelForValue(d+f)}return u.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,n){return Math.max(Math.min(t,n),e)}var e,n,i,a,o=this,s=o.getMeta(),l=o.chart.chartArea,u=s.data||[];if(s.dataset._model.spanGaps&&(u=u.filter(function(t){return!t._model.skip})),"monotone"===s.dataset._model.cubicInterpolationMode)r.splineCurveMonotone(u);else for(e=0,n=u.length;e<n;++e)i=u[e]._model,a=r.splineCurve(r.previousItem(u,e)._model,i,r.nextItem(u,e)._model,s.dataset._model.tension),i.controlPointPreviousX=a.previous.x,i.controlPointPreviousY=a.previous.y,i.controlPointNextX=a.next.x,i.controlPointNextY=a.next.y;if(o.chart.options.elements.line.capBezierPoints)for(e=0,n=u.length;e<n;++e)(i=u[e]._model).controlPointPreviousX=t(i.controlPointPreviousX,l.left,l.right),i.controlPointPreviousY=t(i.controlPointPreviousY,l.top,l.bottom),i.controlPointNextX=t(i.controlPointNextX,l.left,l.right),i.controlPointNextY=t(i.controlPointNextY,l.top,l.bottom)},draw:function(){var t=this,n=t.chart,i=t.getMeta(),a=i.data||[],o=n.chartArea,s=a.length,l=0;for(r.canvas.clipArea(n.ctx,o),e(t.getDataset(),n.options)&&i.dataset.draw(),r.canvas.unclipArea(n.ctx);l<s;++l)a[l].draw(o)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model;a.radius=i.hoverRadius||r.valueAtIndexOrDefault(e.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),a.backgroundColor=i.hoverBackgroundColor||r.valueAtIndexOrDefault(e.pointHoverBackgroundColor,n,r.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor||r.valueAtIndexOrDefault(e.pointHoverBorderColor,n,r.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth||r.valueAtIndexOrDefault(e.pointHoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this,n=e.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=t._model;void 0!==n.radius&&void 0===n.pointRadius&&(n.pointRadius=n.radius),o.radius=a.radius||r.valueAtIndexOrDefault(n.pointRadius,i,e.chart.options.elements.point.radius),o.backgroundColor=e.getPointBackgroundColor(t,i),o.borderColor=e.getPointBorderColor(t,i),o.borderWidth=e.getPointBorderWidth(t,i)}})}},{25:25,40:40,45:45}],19:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._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=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},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),o=e.datasets[0],s=a.data[i].custom||{},l=r.valueAtIndexOrDefault,u=t.options.elements.arc;return{text:n,fillStyle:s.backgroundColor?s.backgroundColor:l(o.backgroundColor,i,u.backgroundColor),strokeStyle:s.borderColor?s.borderColor:l(o.borderColor,i,u.borderColor),lineWidth:s.borderWidth?s.borderWidth:l(o.borderWidth,i,u.borderWidth),hidden:isNaN(o.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}}}}),e.exports=function(t){t.controllers.polarArea=t.DatasetController.extend({dataElementType:a.Arc,linkScales:r.noop,update:function(t){var e=this,n=e.chart,i=n.chartArea,a=e.getMeta(),o=n.options,s=o.elements.arc,l=Math.min(i.right-i.left,i.bottom-i.top);n.outerRadius=Math.max((l-s.borderWidth/2)/2,0),n.innerRadius=Math.max(o.cutoutPercentage?n.outerRadius/100*o.cutoutPercentage:1,0),n.radiusLength=(n.outerRadius-n.innerRadius)/n.getVisibleDatasetCount(),e.outerRadius=n.outerRadius-n.radiusLength*e.index,e.innerRadius=e.outerRadius-n.radiusLength,a.count=e.countVisibleElements(),r.each(a.data,function(n,i){e.updateElement(n,i,t)})},updateElement:function(t,e,n){for(var i=this,a=i.chart,o=i.getDataset(),s=a.options,l=s.animation,u=a.scale,d=a.data.labels,c=i.calculateCircumference(o.data[e]),h=u.xCenter,f=u.yCenter,g=0,m=i.getMeta(),p=0;p<e;++p)isNaN(o.data[p])||m.data[p].hidden||++g;var v=s.startAngle,y=t.hidden?0:u.getDistanceFromCenterForValue(o.data[e]),b=v+c*g,x=b+(t.hidden?0:c),_=l.animateScale?0:u.getDistanceFromCenterForValue(o.data[e]);r.extend(t,{_datasetIndex:i.index,_index:e,_scale:u,_model:{x:h,y:f,innerRadius:0,outerRadius:n?_:y,startAngle:n&&l.animateRotate?v:b,endAngle:n&&l.animateRotate?v:x,label:r.valueAtIndexOrDefault(d,e,d[e])}}),i.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),n=0;return r.each(e.data,function(e,i){isNaN(t.data[i])||e.hidden||n++}),n},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{25:25,40:40,45:45}],20:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("radar",{scale:{type:"radialLinear"},elements:{line:{tension:0}}}),e.exports=function(t){t.controllers.radar=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,linkScales:r.noop,update:function(t){var e=this,n=e.getMeta(),i=n.dataset,a=n.data,o=i.custom||{},s=e.getDataset(),l=e.chart.options.elements.line,u=e.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),r.extend(n.dataset,{_datasetIndex:e.index,_scale:u,_children:a,_loop:!0,_model:{tension:o.tension?o.tension:r.valueOrDefault(s.lineTension,l.tension),backgroundColor:o.backgroundColor?o.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:s.borderWidth||l.borderWidth,borderColor:o.borderColor?o.borderColor:s.borderColor||l.borderColor,fill:o.fill?o.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:o.borderCapStyle?o.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:o.borderDash?o.borderDash:s.borderDash||l.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle}}),n.dataset.pivot(),r.each(a,function(n,i){e.updateElement(n,i,t)},e),e.updateBezierControlPoints()},updateElement:function(t,e,n){var i=this,a=t.custom||{},o=i.getDataset(),s=i.chart.scale,l=i.chart.options.elements.point,u=s.getPointPositionForValue(e,o.data[e]);void 0!==o.radius&&void 0===o.pointRadius&&(o.pointRadius=o.radius),void 0!==o.hitRadius&&void 0===o.pointHitRadius&&(o.pointHitRadius=o.hitRadius),r.extend(t,{_datasetIndex:i.index,_index:e,_scale:s,_model:{x:n?s.xCenter:u.x,y:n?s.yCenter:u.y,tension:a.tension?a.tension:r.valueOrDefault(o.lineTension,i.chart.options.elements.line.tension),radius:a.radius?a.radius:r.valueAtIndexOrDefault(o.pointRadius,e,l.radius),backgroundColor:a.backgroundColor?a.backgroundColor:r.valueAtIndexOrDefault(o.pointBackgroundColor,e,l.backgroundColor),borderColor:a.borderColor?a.borderColor:r.valueAtIndexOrDefault(o.pointBorderColor,e,l.borderColor),borderWidth:a.borderWidth?a.borderWidth:r.valueAtIndexOrDefault(o.pointBorderWidth,e,l.borderWidth),pointStyle:a.pointStyle?a.pointStyle:r.valueAtIndexOrDefault(o.pointStyle,e,l.pointStyle),hitRadius:a.hitRadius?a.hitRadius:r.valueAtIndexOrDefault(o.pointHitRadius,e,l.hitRadius)}}),t._model.skip=a.skip?a.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,e=this.getMeta();r.each(e.data,function(n,i){var a=n._model,o=r.splineCurve(r.previousItem(e.data,i,!0)._model,a,r.nextItem(e.data,i,!0)._model,a.tension);a.controlPointPreviousX=Math.max(Math.min(o.previous.x,t.right),t.left),a.controlPointPreviousY=Math.max(Math.min(o.previous.y,t.bottom),t.top),a.controlPointNextX=Math.max(Math.min(o.next.x,t.right),t.left),a.controlPointNextY=Math.max(Math.min(o.next.y,t.bottom),t.top),n.pivot()})},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t.custom||{},i=t._index,a=t._model;a.radius=n.hoverRadius?n.hoverRadius:r.valueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),a.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:r.valueAtIndexOrDefault(e.pointHoverBackgroundColor,i,r.getHoverColor(a.backgroundColor)),a.borderColor=n.hoverBorderColor?n.hoverBorderColor:r.valueAtIndexOrDefault(e.pointHoverBorderColor,i,r.getHoverColor(a.borderColor)),a.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:r.valueAtIndexOrDefault(e.pointHoverBorderWidth,i,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t.custom||{},i=t._index,a=t._model,o=this.chart.options.elements.point;a.radius=n.radius?n.radius:r.valueAtIndexOrDefault(e.pointRadius,i,o.radius),a.backgroundColor=n.backgroundColor?n.backgroundColor:r.valueAtIndexOrDefault(e.pointBackgroundColor,i,o.backgroundColor),a.borderColor=n.borderColor?n.borderColor:r.valueAtIndexOrDefault(e.pointBorderColor,i,o.borderColor),a.borderWidth=n.borderWidth?n.borderWidth:r.valueAtIndexOrDefault(e.pointBorderWidth,i,o.borderWidth)}})}},{25:25,40:40,45:45}],21:[function(t,e,n){"use strict";t(25)._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},showLines:!1,tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),e.exports=function(t){t.controllers.scatter=t.controllers.line}},{25:25}],22:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:r.noop,onComplete:r.noop}}),e.exports=function(t){t.Animation=a.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,n,i){var a,r,o=this.animations;for(e.chart=t,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=r.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=r.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),n=0;t.dropFrames>1&&(n=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+n);var i=Date.now();t.dropFrames+=(i-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,n,i=this.animations,a=0;a<i.length;)n=(e=i[a]).chart,e.currentStep=(e.currentStep||0)+t,e.currentStep=Math.min(e.currentStep,e.numSteps),r.callback(e.render,[n,e],n),r.callback(e.onAnimationProgress,[e],n),e.currentStep>=e.numSteps?(r.callback(e.onAnimationComplete,[e],n),n.animating=!1,i.splice(a,1)):++a}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{25:25,26:26,45:45}],23:[function(t,e,n){"use strict";var i=t(25),a=t(45),r=t(28),o=t(48);e.exports=function(t){function e(t){var e=(t=t||{}).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=a.configMerge(i.global,i[t.type],t.options||{}),t}function n(t){var e=t.options;e.scale?t.scale.options=e.scale:e.scales&&e.scales.xAxes.concat(e.scales.yAxes).forEach(function(e){t.scales[e.id].options=e}),t.tooltip._options=e.tooltips}function s(t){return"top"===t||"bottom"===t}var l=t.plugins;t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(n,i){var r=this;i=e(i);var s=o.acquireContext(n,i),l=s&&s.canvas,u=l&&l.height,d=l&&l.width;r.id=a.uid(),r.ctx=s,r.canvas=l,r.config=i,r.width=d,r.height=u,r.aspectRatio=u?d/u:null,r.options=i.options,r._bufferedRender=!1,r.chart=r,r.controller=r,t.instances[r.id]=r,Object.defineProperty(r,"data",{get:function(){return r.config.data},set:function(t){r.config.data=t}}),s&&l?(r.initialize(),r.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return l.notify(t,"beforeInit"),a.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildScales(),t.initToolTip(),l.notify(t,"afterInit"),t},clear:function(){return a.canvas.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,r=n.maintainAspectRatio&&e.aspectRatio||null,o=Math.max(0,Math.floor(a.getMaximumWidth(i))),s=Math.max(0,Math.floor(r?o/r:a.getMaximumHeight(i)));if((e.width!==o||e.height!==s)&&(i.width=e.width=o,i.height=e.height=s,i.style.width=o+"px",i.style.height=s+"px",a.retinaScale(e,n.devicePixelRatio),!t)){var u={width:o,height:s};l.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),n&&(n.id=n.id||"scale")},buildScales:function(){var e=this,n=e.options,i=e.scales={},r=[];n.scales&&(r=r.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&r.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(r,function(n){var r=n.options,o=a.valueOrDefault(r.type,n.dtype),l=t.scaleService.getScaleConstructor(o);if(l){s(r.position)!==s(n.dposition)&&(r.position=n.dposition);var u=new l({id:r.id,options:r,ctx:e.ctx,chart:e});i[u.id]=u,u.mergeTicksOptions(),n.isDefault&&(e.scale=u)}}),t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,n=[],i=[];return a.each(e.data.datasets,function(a,r){var o=e.getDatasetMeta(r),s=a.type||e.config.type;if(o.type&&o.type!==s&&(e.destroyDatasetMeta(r),o=e.getDatasetMeta(r)),o.type=s,n.push(o.type),o.controller)o.controller.updateIndex(r);else{var l=t.controllers[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(e,r),i.push(o.controller)}},e),i},resetElements:function(){var t=this;a.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=this;if(t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]}),n(e),!1!==l.notify(e,"beforeUpdate")){e.tooltip._data=e.data;var i=e.buildOrUpdateControllers();a.each(e.data.datasets,function(t,n){e.getDatasetMeta(n).controller.buildOrUpdateElements()},e),e.updateLayout(),a.each(i,function(t){t.reset()}),e.updateDatasets(),l.notify(e,"afterUpdate"),e._bufferedRender?e._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:e.render(t)}},updateLayout:function(){var e=this;!1!==l.notify(e,"beforeLayout")&&(t.layoutService.update(this,this.width,this.height),l.notify(e,"afterScaleUpdate"),l.notify(e,"afterLayout"))},updateDatasets:function(){var t=this;if(!1!==l.notify(t,"beforeDatasetsUpdate")){for(var e=0,n=t.data.datasets.length;e<n;++e)t.updateDataset(e);l.notify(t,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this,n=e.getDatasetMeta(t),i={meta:n,index:t};!1!==l.notify(e,"beforeDatasetUpdate",[i])&&(n.controller.update(),l.notify(e,"afterDatasetUpdate",[i]))},render:function(e){var n=this;e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]});var i=e.duration,r=e.lazy;if(!1!==l.notify(n,"beforeRender")){var o=n.options.animation,s=function(t){l.notify(n,"afterRender"),a.callback(o&&o.onComplete,[t],n)};if(o&&(void 0!==i&&0!==i||void 0===i&&0!==o.duration)){var u=new t.Animation({numSteps:(i||o.duration)/16.66,easing:e.easing||o.easing,render:function(t,e){var n=a.easing.effects[e.easing],i=e.currentStep,r=i/e.numSteps;t.draw(n(r),r,i)},onAnimationProgress:o.onProgress,onAnimationComplete:s});t.animationService.addAnimation(n,u,i,r)}else n.draw(),s(new t.Animation({numSteps:0,chart:n}));return n}},draw:function(t){var e=this;e.clear(),a.isNullOrUndef(t)&&(t=1),e.transition(t),!1!==l.notify(e,"beforeDraw",[t])&&(a.each(e.boxes,function(t){t.draw(e.chartArea)},e),e.scale&&e.scale.draw(),e.drawDatasets(t),e.tooltip.draw(),l.notify(e,"afterDraw",[t]))},transition:function(t){for(var e=this,n=0,i=(e.data.datasets||[]).length;n<i;++n)e.isDatasetVisible(n)&&e.getDatasetMeta(n).controller.transition(t);e.tooltip.transition(t)},drawDatasets:function(t){var e=this;if(!1!==l.notify(e,"beforeDatasetsDraw",[t])){for(var n=(e.data.datasets||[]).length-1;n>=0;--n)e.isDatasetVisible(n)&&e.drawDataset(n,t);l.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n=this,i=n.getDatasetMeta(t),a={meta:i,index:t,easingValue:e};!1!==l.notify(n,"beforeDatasetDraw",[a])&&(i.controller.draw(e),l.notify(n,"afterDatasetDraw",[a]))},getElementAtEvent:function(t){return r.modes.single(this,t)},getElementsAtEvent:function(t){return r.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return r.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=r.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return r.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this,n=e.data.datasets[t];n._meta||(n._meta={});var i=n._meta[e.id];return i||(i=n._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},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 e,n,i=this,r=i.canvas;for(i.stop(),e=0,n=i.data.datasets.length;e<n;++e)i.destroyDatasetMeta(e);r&&(i.unbindEvents(),a.canvas.clear(i),o.releaseContext(i.ctx),i.canvas=null,i.ctx=null),l.notify(i,"destroy"),delete t.instances[i.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this,e=t._listeners={},n=function(){t.eventHandler.apply(t,arguments)};a.each(t.options.events,function(i){o.addEventListener(t,i,n),e[i]=n}),t.options.responsive&&(n=function(){t.resize()},o.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,a.each(e,function(e,n){o.removeEventListener(t,n,e)}))},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"setHoverStyle":"removeHoverStyle";for(a=0,r=t.length;a<r;++a)(i=t[a])&&this.getDatasetMeta(i._datasetIndex).controller[o](i)},eventHandler:function(t){var e=this,n=e.tooltip;if(!1!==l.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);i|=n&&n.handleEvent(t),l.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):i&&!e.animating&&(e.stop(),e.render(e.options.hover.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e=this,n=e.options||{},i=n.hover,r=!1;return e.lastActive=e.lastActive||[],"mouseout"===t.type?e.active=[]:e.active=e.getElementsAtEventForMode(t,i.mode,i),a.callback(n.onHover||n.hover.onHover,[t.native,e.active],e),"mouseup"!==t.type&&"click"!==t.type||n.onClick&&n.onClick.call(e,t.native,e.active),e.lastActive.length&&e.updateHoverStyle(e.lastActive,i.mode,!1),e.active.length&&i.mode&&e.updateHoverStyle(e.active,i.mode,!0),r=!a.arrayEquals(e.active,e.lastActive),e.lastActive=e.active,r}}),t.Controller=t}},{25:25,28:28,45:45,48:48}],24:[function(t,e,n){"use strict";var i=t(45);e.exports=function(t){function e(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),a.forEach(function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),a=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),r=a.apply(this,e);return i.each(t._chartjs.listeners,function(t){"function"==typeof t[n]&&t[n].apply(t,e)}),r}})}))}function n(t,e){var n=t._chartjs;if(n){var i=n.listeners,r=i.indexOf(e);-1!==r&&i.splice(r,1),i.length>0||(a.forEach(function(e){delete t[e]}),delete t._chartjs)}}var a=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.getDataset();null===e.xAxisID&&(e.xAxisID=n.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=n.yAxisID||t.chart.options.scales.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]},reset:function(){this.update(!0)},destroy:function(){this._data&&n(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,n=e.dataElementType;return n&&new n({_chart:e.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,n=this,i=n.getMeta(),a=n.getDataset().data||[],r=i.data;for(t=0,e=a.length;t<e;++t)r[t]=r[t]||n.createMetaData(t);i.dataset=i.dataset||n.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=this,i=t.getDataset(),a=i.data||(i.data=[]);t._data!==a&&(t._data&&n(t._data,t),e(a,t),t._data=a),t.resyncElements()},update:i.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()},removeHoverStyle:function(t,e){var n=this.chart.data.datasets[t._datasetIndex],a=t._index,r=t.custom||{},o=i.valueAtIndexOrDefault,s=t._model;s.backgroundColor=r.backgroundColor?r.backgroundColor:o(n.backgroundColor,a,e.backgroundColor),s.borderColor=r.borderColor?r.borderColor:o(n.borderColor,a,e.borderColor),s.borderWidth=r.borderWidth?r.borderWidth:o(n.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},r=i.valueAtIndexOrDefault,o=i.getHoverColor,s=t._model;s.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:r(e.hoverBackgroundColor,n,o(s.backgroundColor)),s.borderColor=a.hoverBorderColor?a.hoverBorderColor:r(e.hoverBorderColor,n,o(s.borderColor)),s.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:r(e.hoverBorderWidth,n,s.borderWidth)},resyncElements:function(){var t=this,e=t.getMeta(),n=t.getDataset().data,i=e.data.length,a=n.length;a<i?e.data.splice(a,i-a):a>i&&t.insertElements(i,a-i)},insertElements:function(t,e){for(var n=0;n<e;++n)this.addElementAndReset(t+n)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},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)}}),t.DatasetController.extend=i.inherits}},{45:45}],25:[function(t,e,n){"use strict";var i=t(45);e.exports={_set:function(t,e){return i.merge(this[t]||(this[t]={}),e)}}},{45:45}],26:[function(t,e,n){"use strict";function i(t,e,n,i){var r,o,s,l,u,d,c,h,f,g=Object.keys(n);for(r=0,o=g.length;r<o;++r)if(s=g[r],d=n[s],e.hasOwnProperty(s)||(e[s]=d),(l=e[s])!==d&&"_"!==s[0]){if(t.hasOwnProperty(s)||(t[s]=l),u=t[s],(c=typeof d)===typeof u)if("string"===c){if((h=a(u)).valid&&(f=a(d)).valid){e[s]=f.mix(h,i).rgbString();continue}}else if("number"===c&&isFinite(u)&&isFinite(d)){e[s]=u+(d-u)*i;continue}e[s]=d}}var a=t(2),r=t(45),o=function(t){r.extend(this,t),this.initialize.apply(this,arguments)};r.extend(o.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=r.clone(t._model)),t._start={},t},transition:function(t){var e=this,n=e._model,a=e._start,r=e._view;return n&&1!==t?(r||(r=e._view={}),a||(a=e._start={}),i(a,r,n,t),e):(e._view=n,e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return r.isNumber(this._model.x)&&r.isNumber(this._model.y)}}),o.extend=r.inherits,e.exports=o},{2:2,45:45}],27:[function(t,e,n){"use strict";var i=t(2),a=t(25),r=t(45);e.exports=function(t){function e(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 n(t){return void 0!==t&&null!==t&&"none"!==t}function o(t,i,a){var r=document.defaultView,o=t.parentNode,s=r.getComputedStyle(t)[i],l=r.getComputedStyle(o)[i],u=n(s),d=n(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,a):c,d?e(l,o,a):c):"none"}r.extend=function(t){for(var e=1,n=arguments.length;e<n;e++)r.each(arguments[e],function(e,n){t[n]=e});return t},r.configMerge=function(){return r.merge(r.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,n,i,a){var o=n[e]||{},s=i[e];"scales"===e?n[e]=r.scaleMerge(o,s):"scale"===e?n[e]=r.merge(o,[t.scaleService.getScaleDefaults(s.type),s]):r._merger(e,n,i,a)}})},r.scaleMerge=function(){return r.merge(r.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,n,i,a){if("xAxes"===e||"yAxes"===e){var o,s,l,u=i[e].length;for(n[e]||(n[e]=[]),o=0;o<u;++o)l=i[e][o],s=r.valueOrDefault(l.type,"xAxes"===e?"category":"linear"),o>=n[e].length&&n[e].push({}),!n[e][o].type||l.type&&l.type!==n[e][o].type?r.merge(n[e][o],[t.scaleService.getScaleDefaults(s),l]):r.merge(n[e][o],l)}else r._merger(e,n,i,a)}})},r.where=function(t,e){if(r.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return r.each(t,function(t){e(t)&&n.push(t)}),n},r.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},r.findNextWhere=function(t,e,n){r.isNullOrUndef(n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},r.findPreviousWhere=function(t,e,n){r.isNullOrUndef(n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},r.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=r.inherits,t&&r.extend(n.prototype,t),n.__super__=e.prototype,n},r.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},r.almostEquals=function(t,e,n){return Math.abs(t-e)<n},r.almostWhole=function(t,e){var n=Math.round(t);return n-e<t&&n+e>t},r.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},r.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},r.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0==(t=+t)||isNaN(t)?t:t>0?1:-1},r.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},r.toRadians=function(t){return t*(Math.PI/180)},r.toDegrees=function(t){return t*(180/Math.PI)},r.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}},r.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},r.aliasPixel=function(t){return t%2==0?0:.5},r.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),c=i*(u=isNaN(u)?0:u),h=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-c*(o.x-a.x),y:r.y-c*(o.y-a.y)},next:{x:r.x+h*(o.x-a.x),y:r.y+h*(o.y-a.y)}}},r.EPSILON=Number.EPSILON||1e-14,r.splineCurveMonotone=function(t){var e,n,i,a,o=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),s=o.length;for(e=0;e<s;++e)if(!(i=o[e]).model.skip){if(n=e>0?o[e-1]:null,(a=e<s-1?o[e+1]:null)&&!a.model.skip){var l=a.model.x-i.model.x;i.deltaK=0!==l?(a.model.y-i.model.y)/l: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}var u,d,c,h;for(e=0;e<s-1;++e)i=o[e],a=o[e+1],i.model.skip||a.model.skip||(r.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(u=i.mK/i.deltaK,d=a.mK/i.deltaK,(h=Math.pow(u,2)+Math.pow(d,2))<=9||(c=3/Math.sqrt(h),i.mK=u*c*i.deltaK,a.mK=d*c*i.deltaK)));var f;for(e=0;e<s;++e)(i=o[e]).model.skip||(n=e>0?o[e-1]:null,a=e<s-1?o[e+1]:null,n&&!n.model.skip&&(f=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-f,i.model.controlPointPreviousY=i.model.y-f*i.mK),a&&!a.model.skip&&(f=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+f,i.model.controlPointNextY=i.model.y+f*i.mK))},r.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]},r.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},r.niceNum=function(t,e){var n=Math.floor(r.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)},r.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)},r.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,o=t.currentTarget||t.srcElement,s=o.getBoundingClientRect(),l=a.touches;l&&l.length>0?(n=l[0].clientX,i=l[0].clientY):(n=a.clientX,i=a.clientY);var u=parseFloat(r.getStyle(o,"padding-left")),d=parseFloat(r.getStyle(o,"padding-top")),c=parseFloat(r.getStyle(o,"padding-right")),h=parseFloat(r.getStyle(o,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return n=Math.round((n-s.left-u)/f*o.width/e.currentDevicePixelRatio),i=Math.round((i-s.top-d)/g*o.height/e.currentDevicePixelRatio),{x:n,y:i}},r.getConstraintWidth=function(t){return o(t,"max-width","clientWidth")},r.getConstraintHeight=function(t){return o(t,"max-height","clientHeight")},r.getMaximumWidth=function(t){var e=t.parentNode;if(!e)return t.clientWidth;var n=parseInt(r.getStyle(e,"padding-left"),10),i=parseInt(r.getStyle(e,"padding-right"),10),a=e.clientWidth-n-i,o=r.getConstraintWidth(t);return isNaN(o)?a:Math.min(a,o)},r.getMaximumHeight=function(t){var e=t.parentNode;if(!e)return t.clientHeight;var n=parseInt(r.getStyle(e,"padding-top"),10),i=parseInt(r.getStyle(e,"padding-bottom"),10),a=e.clientHeight-n-i,o=r.getConstraintHeight(t);return isNaN(o)?a:Math.min(a,o)},r.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},r.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||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=a+"px",i.style.width=r+"px"}},r.fontString=function(t,e,n){return e+" "+t+"px "+n},r.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},o=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},o=i.garbageCollect=[],i.font=e),t.font=e;var s=0;r.each(n,function(e){void 0!==e&&null!==e&&!0!==r.isArray(e)?s=r.measureText(t,a,o,s,e):r.isArray(e)&&r.each(e,function(e){void 0===e||null===e||r.isArray(e)||(s=r.measureText(t,a,o,s,e))})});var l=o.length/2;if(l>n.length){for(var u=0;u<l;u++)delete a[o[u]];o.splice(0,l)}return s},r.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},r.numberOfLabelLines=function(t){var e=1;return r.each(t,function(t){r.isArray(t)&&t.length>e&&(e=t.length)}),e},r.color=i?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),i(t)}:function(t){return console.error("Color.js not found!"),t},r.getHoverColor=function(t){return t instanceof CanvasPattern?t:r.color(t).saturate(.5).darken(.1).rgbString()}}},{2:2,25:25,45:45}],28:[function(t,e,n){"use strict";function i(t,e){return t.native?{x:t.x,y:t.y}:u.getRelativePosition(t,e)}function a(t,e){var n,i,a,r,o;for(i=0,r=t.data.datasets.length;i<r;++i)if(t.isDatasetVisible(i))for(a=0,o=(n=t.getDatasetMeta(i)).data.length;a<o;++a){var s=n.data[a];s._view.skip||e(s)}}function r(t,e){var n=[];return a(t,function(t){t.inRange(e.x,e.y)&&n.push(t)}),n}function o(t,e,n,i){var r=Number.POSITIVE_INFINITY,o=[];return a(t,function(t){if(!n||t.inRange(e.x,e.y)){var a=t.getCenterPoint(),s=i(e,a);s<r?(o=[t],r=s):s===r&&o.push(t)}}),o}function s(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 l(t,e,n){var a=i(e,t);n.axis=n.axis||"x";var l=s(n.axis),u=n.intersect?r(t,a):o(t,a,!1,l),d=[];return u.length?(t.data.datasets.forEach(function(e,n){if(t.isDatasetVisible(n)){var i=t.getDatasetMeta(n).data[u[0]._index];i&&!i._view.skip&&d.push(i)}}),d):[]}var u=t(45);e.exports={modes:{single:function(t,e){var n=i(e,t),r=[];return a(t,function(t){if(t.inRange(n.x,n.y))return r.push(t),r}),r.slice(0,1)},label:l,index:l,dataset:function(t,e,n){var a=i(e,t);n.axis=n.axis||"xy";var l=s(n.axis),u=n.intersect?r(t,a):o(t,a,!1,l);return u.length>0&&(u=t.getDatasetMeta(u[0]._datasetIndex).data),u},"x-axis":function(t,e){return l(t,e,{intersect:!0})},point:function(t,e){return r(t,i(e,t))},nearest:function(t,e,n){var a=i(e,t);n.axis=n.axis||"xy";var r=s(n.axis),l=o(t,a,n.intersect,r);return l.length>1&&l.sort(function(t,e){var n=t.getArea()-e.getArea();return 0===n&&(n=t._datasetIndex-e._datasetIndex),n}),l.slice(0,1)},x:function(t,e,n){var r=i(e,t),o=[],s=!1;return a(t,function(t){t.inXRange(r.x)&&o.push(t),t.inRange(r.x,r.y)&&(s=!0)}),n.intersect&&!s&&(o=[]),o},y:function(t,e,n){var r=i(e,t),o=[],s=!1;return a(t,function(t){t.inYRange(r.y)&&o.push(t),t.inRange(r.x,r.y)&&(s=!0)}),n.intersect&&!s&&(o=[]),o}}}},{45:45}],29:[function(t,e,n){"use strict";t(25)._set("global",{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},{25:25}],30:[function(t,e,n){"use strict";var i=t(45);e.exports=function(t){function e(t,e){return i.where(t,function(t){return t.position===e})}function n(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i._tmpIndex_-a._tmpIndex_:i.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,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,a,r){function o(t){var e=i.findNextWhere(D,function(e){return e.box===t});if(e)if(t.isHorizontal()){var n={left:Math.max(A,C),right:Math.max(O,P),top:0,bottom:0};t.update(t.fullWidth?b:M,x/2,n)}else t.update(e.minSize.width,S)}function s(t){t.isHorizontal()?(t.left=t.fullWidth?d:A,t.right=t.fullWidth?a-c:A+M,t.top=B,t.bottom=B+t.height,B=t.bottom):(t.left=z,t.right=z+t.width,t.top=F,t.bottom=F+S,z=t.right)}if(t){var l=t.options.layout||{},u=i.options.toPadding(l.padding),d=u.left,c=u.right,h=u.top,f=u.bottom,g=e(t.boxes,"left"),m=e(t.boxes,"right"),p=e(t.boxes,"top"),v=e(t.boxes,"bottom"),y=e(t.boxes,"chartArea");n(g,!0),n(m,!1),n(p,!0),n(v,!1);var b=a-d-c,x=r-h-f,_=x/2,k=(a-b/2)/(g.length+m.length),w=(r-_)/(p.length+v.length),M=b,S=x,D=[];i.each(g.concat(m,p,v),function(t){var e,n=t.isHorizontal();n?(e=t.update(t.fullWidth?b:M,w),S-=e.height):(e=t.update(k,_),M-=e.width),D.push({horizontal:n,minSize:e,box:t})});var C=0,P=0,T=0,I=0;i.each(p.concat(v),function(t){if(t.getPadding){var e=t.getPadding();C=Math.max(C,e.left),P=Math.max(P,e.right)}}),i.each(g.concat(m),function(t){if(t.getPadding){var e=t.getPadding();T=Math.max(T,e.top),I=Math.max(I,e.bottom)}});var A=d,O=c,F=h,R=f;i.each(g.concat(m),o),i.each(g,function(t){A+=t.width}),i.each(m,function(t){O+=t.width}),i.each(p.concat(v),o),i.each(p,function(t){F+=t.height}),i.each(v,function(t){R+=t.height}),i.each(g.concat(m),function(t){var e=i.findNextWhere(D,function(e){return e.box===t}),n={left:0,right:0,top:F,bottom:R};e&&t.update(e.minSize.width,S,n)}),A=d,O=c,F=h,R=f,i.each(g,function(t){A+=t.width}),i.each(m,function(t){O+=t.width}),i.each(p,function(t){F+=t.height}),i.each(v,function(t){R+=t.height});var L=Math.max(C-A,0);A+=L,O+=Math.max(P-O,0);var W=Math.max(T-F,0);F+=W,R+=Math.max(I-R,0);var Y=r-F-R,N=a-A-O;N===M&&Y===S||(i.each(g,function(t){t.height=Y}),i.each(m,function(t){t.height=Y}),i.each(p,function(t){t.fullWidth||(t.width=N)}),i.each(v,function(t){t.fullWidth||(t.width=N)}),S=Y,M=N);var z=d+L,B=h+W;i.each(g.concat(p),s),z+=M,B+=S,i.each(m,s),i.each(v,s),t.chartArea={left:A,top:F,right:A+M,bottom:F+S},i.each(y,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(M,S)})}}}}},{45:45}],31:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{plugins:{}}),e.exports=function(t){t.plugins={_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(a=l[i],r=a.plugin,"function"==typeof(s=r[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=[],a=[],o=t&&t.config||{},s=o.options&&o.options.plugins||{};return this._plugins.concat(o.plugins||[]).forEach(function(t){if(-1===n.indexOf(t)){var e=t.id,o=s[e];!1!==o&&(!0===o&&(o=r.clone(i.global.plugins[e])),n.push(t),a.push({plugin:t,options:o||{}}))}}),e.descriptors=a,e.id=this._cacheId,a}},t.pluginService=t.plugins,t.PluginBase=a.extend({})}},{25:25,26:26,45:45}],32:[function(t,e,n){"use strict";function i(t){var e,n,i=[];for(e=0,n=t.length;e<n;++e)i.push(t[e].label);return i}function a(t,e,n){var i=t.getPixelForTick(e);return n&&(i-=0===e?(t.getPixelForTick(1)-i)/2:(i-t.getPixelForTick(e-1))/2),i}var r=t(25),o=t(26),s=t(45),l=t(34);r._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:"",lineHeight:1.2,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:l.formatters.values,minor:{},major:{}}}),e.exports=function(t){function e(t,e,n){return s.isArray(e)?s.longestText(t,n,e):t.measureText(e).width}function n(t){var e=s.valueOrDefault,n=r.global,i=e(t.fontSize,n.defaultFontSize),a=e(t.fontStyle,n.defaultFontStyle),o=e(t.fontFamily,n.defaultFontFamily);return{size:i,style:a,family:o,font:s.fontString(i,a,o)}}function l(t){return s.options.toLineHeight(s.valueOrDefault(t.lineHeight,1.2),s.valueOrDefault(t.fontSize,r.global.defaultFontSize))}t.Scale=o.extend({getPadding:function(){var t=this;return{left:t.paddingLeft||0,top:t.paddingTop||0,right:t.paddingRight||0,bottom:t.paddingBottom||0}},getTicks:function(){return this._ticks},mergeTicksOptions:function(){var t=this.options.ticks;!1===t.minor&&(t.minor={display:!1}),!1===t.major&&(t.major={display:!1});for(var e in t)"major"!==e&&"minor"!==e&&(void 0===t.minor[e]&&(t.minor[e]=t[e]),void 0===t.major[e]&&(t.major[e]=t[e]))},beforeUpdate:function(){s.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var i,a,r,o,l,u,d=this;for(d.beforeUpdate(),d.maxWidth=t,d.maxHeight=e,d.margins=s.extend({left:0,right:0,top:0,bottom:0},n),d.longestTextCache=d.longestTextCache||{},d.beforeSetDimensions(),d.setDimensions(),d.afterSetDimensions(),d.beforeDataLimits(),d.determineDataLimits(),d.afterDataLimits(),d.beforeBuildTicks(),l=d.buildTicks()||[],d.afterBuildTicks(),d.beforeTickToLabelConversion(),r=d.convertTicksToLabels(l)||d.ticks,d.afterTickToLabelConversion(),d.ticks=r,i=0,a=r.length;i<a;++i)o=r[i],(u=l[i])?u.label=o:l.push(u={label:o,major:!1});return d._ticks=l,d.beforeCalculateTickRotation(),d.calculateTickRotation(),d.afterCalculateTickRotation(),d.beforeFit(),d.fit(),d.afterFit(),d.afterUpdate(),d.minSize},afterUpdate:function(){s.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){s.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(){s.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){s.callback(this.options.beforeDataLimits,[this])},determineDataLimits:s.noop,afterDataLimits:function(){s.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){s.callback(this.options.beforeBuildTicks,[this])},buildTicks:s.noop,afterBuildTicks:function(){s.callback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){s.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this,e=t.options.ticks;t.ticks=t.ticks.map(e.userCallback||e.callback,this)},afterTickToLabelConversion:function(){s.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){s.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t=this,e=t.ctx,a=t.options.ticks,r=i(t._ticks),o=n(a);e.font=o.font;var l=a.minRotation||0;if(r.length&&t.options.display&&t.isHorizontal())for(var u,d=s.longestText(e,o.font,r,t.longestTextCache),c=d,h=t.getPixelForTick(1)-t.getPixelForTick(0)-6;c>h&&l<a.maxRotation;){var f=s.toRadians(l);if(u=Math.cos(f),Math.sin(f)*d>t.maxHeight){l--;break}l++,c=u*d}t.labelRotation=l},afterCalculateTickRotation:function(){s.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){s.callback(this.options.beforeFit,[this])},fit:function(){var t=this,a=t.minSize={width:0,height:0},r=i(t._ticks),o=t.options,u=o.ticks,d=o.scaleLabel,c=o.gridLines,h=o.display,f=t.isHorizontal(),g=n(u),m=o.gridLines.tickMarkLength;if(a.width=f?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:h&&c.drawTicks?m:0,a.height=f?h&&c.drawTicks?m:0:t.maxHeight,d.display&&h){var p=l(d)+s.options.toPadding(d.padding).height;f?a.height+=p:a.width+=p}if(u.display&&h){var v=s.longestText(t.ctx,g.font,r,t.longestTextCache),y=s.numberOfLabelLines(r),b=.5*g.size,x=t.options.ticks.padding;if(f){t.longestLabelWidth=v;var _=s.toRadians(t.labelRotation),k=Math.cos(_),w=Math.sin(_)*v+g.size*y+b*(y-1)+b;a.height=Math.min(t.maxHeight,a.height+w+x),t.ctx.font=g.font;var M=e(t.ctx,r[0],g.font),S=e(t.ctx,r[r.length-1],g.font);0!==t.labelRotation?(t.paddingLeft="bottom"===o.position?k*M+3:k*b+3,t.paddingRight="bottom"===o.position?k*b+3:k*S+3):(t.paddingLeft=M/2+3,t.paddingRight=S/2+3)}else u.mirror?v=0:v+=x+b,a.width=Math.min(t.maxWidth,a.width+v),t.paddingTop=g.size/2,t.paddingBottom=g.size/2}t.handleMargins(),t.width=a.width,t.height=a.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){s.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(s.isNullOrUndef(t))return NaN;if("number"==typeof t&&!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},getLabelForIndex:s.noop,getPixelForValue:s.noop,getValueForPixel:s.noop,getPixelForTick:function(t){var e=this,n=e.options.offset;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(n?0:1),1),a=i*t+e.paddingLeft;n&&(a+=i/2);var r=e.left+Math.round(a);return r+=e.isFullWidth()?e.margins.left:0}var o=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(o/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,i=e.left+Math.round(n);return i+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this,e=t.min,n=t.max;return t.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0},_autoSkip:function(t){var e,n,i,a,r=this,o=r.isHorizontal(),l=r.options.ticks.minor,u=t.length,d=s.toRadians(r.labelRotation),c=Math.cos(d),h=r.longestLabelWidth*c,f=[];for(l.maxTicksLimit&&(a=l.maxTicksLimit),o&&(e=!1,(h+l.autoSkipPadding)*u>r.width-(r.paddingLeft+r.paddingRight)&&(e=1+Math.floor((h+l.autoSkipPadding)*u/(r.width-(r.paddingLeft+r.paddingRight)))),a&&u>a&&(e=Math.max(e,Math.floor(u/a)))),n=0;n<u;n++)i=t[n],((e>1&&n%e>0||n%e==0&&n+e>=u)&&n!==u-1||s.isNullOrUndef(i.label))&&delete i.label,f.push(i);return f},draw:function(t){var e=this,i=e.options;if(i.display){var o=e.ctx,u=r.global,d=i.ticks.minor,c=i.ticks.major||d,h=i.gridLines,f=i.scaleLabel,g=0!==e.labelRotation,m=e.isHorizontal(),p=d.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),v=s.valueOrDefault(d.fontColor,u.defaultFontColor),y=n(d),b=s.valueOrDefault(c.fontColor,u.defaultFontColor),x=n(c),_=h.drawTicks?h.tickMarkLength:0,k=s.valueOrDefault(f.fontColor,u.defaultFontColor),w=n(f),M=s.options.toPadding(f.padding),S=s.toRadians(e.labelRotation),D=[],C="right"===i.position?e.left:e.right-_,P="right"===i.position?e.left+_:e.right,T="bottom"===i.position?e.top:e.bottom-_,I="bottom"===i.position?e.top+_:e.bottom;if(s.each(p,function(n,r){if(void 0!==n.label){var o,l,c,f,v=n.label;r===e.zeroLineIndex&&i.offset===h.offsetGridLines?(o=h.zeroLineWidth,l=h.zeroLineColor,c=h.zeroLineBorderDash,f=h.zeroLineBorderDashOffset):(o=s.valueAtIndexOrDefault(h.lineWidth,r),l=s.valueAtIndexOrDefault(h.color,r),c=s.valueOrDefault(h.borderDash,u.borderDash),f=s.valueOrDefault(h.borderDashOffset,u.borderDashOffset));var y,b,x,k,w,M,A,O,F,R,L="middle",W="middle",Y=d.padding;if(m){var N=_+Y;"bottom"===i.position?(W=g?"middle":"top",L=g?"right":"center",R=e.top+N):(W=g?"middle":"bottom",L=g?"left":"center",R=e.bottom-N);var z=a(e,r,h.offsetGridLines&&p.length>1);z<e.left&&(l="rgba(0,0,0,0)"),z+=s.aliasPixel(o),F=e.getPixelForTick(r)+d.labelOffset,y=x=w=A=z,b=T,k=I,M=t.top,O=t.bottom}else{var B,V="left"===i.position;d.mirror?(L=V?"left":"right",B=Y):(L=V?"right":"left",B=_+Y),F=V?e.right-B:e.left+B;var H=a(e,r,h.offsetGridLines&&p.length>1);H<e.top&&(l="rgba(0,0,0,0)"),H+=s.aliasPixel(o),R=e.getPixelForTick(r)+d.labelOffset,y=C,x=P,w=t.left,A=t.right,b=k=M=O=H}D.push({tx1:y,ty1:b,tx2:x,ty2:k,x1:w,y1:M,x2:A,y2:O,labelX:F,labelY:R,glWidth:o,glColor:l,glBorderDash:c,glBorderDashOffset:f,rotation:-1*S,label:v,major:n.major,textBaseline:W,textAlign:L})}}),s.each(D,function(t){if(h.display&&(o.save(),o.lineWidth=t.glWidth,o.strokeStyle=t.glColor,o.setLineDash&&(o.setLineDash(t.glBorderDash),o.lineDashOffset=t.glBorderDashOffset),o.beginPath(),h.drawTicks&&(o.moveTo(t.tx1,t.ty1),o.lineTo(t.tx2,t.ty2)),h.drawOnChartArea&&(o.moveTo(t.x1,t.y1),o.lineTo(t.x2,t.y2)),o.stroke(),o.restore()),d.display){o.save(),o.translate(t.labelX,t.labelY),o.rotate(t.rotation),o.font=t.major?x.font:y.font,o.fillStyle=t.major?b:v,o.textBaseline=t.textBaseline,o.textAlign=t.textAlign;var e=t.label;if(s.isArray(e))for(var n=0,i=0;n<e.length;++n)o.fillText(""+e[n],0,i),i+=1.5*y.size;else o.fillText(e,0,0);o.restore()}}),f.display){var A,O,F=0,R=l(f)/2;if(m)A=e.left+(e.right-e.left)/2,O="bottom"===i.position?e.bottom-R-M.bottom:e.top+R+M.top;else{var L="left"===i.position;A=L?e.left+R+M.top:e.right-R-M.top,O=e.top+(e.bottom-e.top)/2,F=L?-.5*Math.PI:.5*Math.PI}o.save(),o.translate(A,O),o.rotate(F),o.textAlign="center",o.textBaseline="middle",o.fillStyle=k,o.font=w.font,o.fillText(f.labelString,0,0),o.restore()}if(h.drawBorder){o.lineWidth=s.valueAtIndexOrDefault(h.lineWidth,0),o.strokeStyle=s.valueAtIndexOrDefault(h.color,0);var W=e.left,Y=e.right,N=e.top,z=e.bottom,B=s.aliasPixel(o.lineWidth);m?(N=z="top"===i.position?e.bottom:e.top,N+=B,z+=B):(W=Y="left"===i.position?e.right:e.left,W+=B,Y+=B),o.beginPath(),o.moveTo(W,N),o.lineTo(Y,z),o.stroke()}}}})}},{25:25,26:26,34:34,45:45}],33:[function(t,e,n){"use strict";var i=t(25),a=t(45);e.exports=function(t){t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=a.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?a.merge({},[i.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){var n=this;n.defaults.hasOwnProperty(t)&&(n.defaults[t]=a.extend(n.defaults[t],e))},addScalesToLayout:function(e){a.each(e.scales,function(n){n.fullWidth=n.options.fullWidth,n.position=n.options.position,n.weight=n.options.weight,t.layoutService.addBox(e,n)})}}}},{25:25,45:45}],34:[function(t,e,n){"use strict";var i=t(45);e.exports={generators:{linear:function(t,e){var n,a=[];if(t.stepSize&&t.stepSize>0)n=t.stepSize;else{var r=i.niceNum(e.max-e.min,!1);n=i.niceNum(r/(t.maxTicks-1),!0)}var o=Math.floor(e.min/n)*n,s=Math.ceil(e.max/n)*n;t.min&&t.max&&t.stepSize&&i.almostWhole((t.max-t.min)/t.stepSize,n/1e3)&&(o=t.min,s=t.max);var l=(s-o)/n;l=i.almostEquals(l,Math.round(l),n/1e3)?Math.round(l):Math.ceil(l),a.push(void 0!==t.min?t.min:o);for(var u=1;u<l;++u)a.push(o+u*n);return a.push(void 0!==t.max?t.max:s),a},logarithmic:function(t,e){var n,a,r=[],o=i.valueOrDefault,s=o(t.min,Math.pow(10,Math.floor(i.log10(e.min)))),l=Math.floor(i.log10(e.max)),u=Math.ceil(e.max/Math.pow(10,l));0===s?(n=Math.floor(i.log10(e.minNotZero)),a=Math.floor(e.minNotZero/Math.pow(10,n)),r.push(s),s=a*Math.pow(10,n)):(n=Math.floor(i.log10(s)),a=Math.floor(s/Math.pow(10,n)));do{r.push(s),10===++a&&(a=1,++n),s=a*Math.pow(10,n)}while(n<l||n===l&&a<u);var d=o(t.max,s);return r.push(d),r}},formatters:{values:function(t){return i.isArray(t)?t:""+t},linear:function(t,e,n){var a=n.length>3?n[2]-n[1]:n[1]-n[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var r=i.log10(Math.abs(a)),o="";if(0!==t){var s=-1*Math.floor(r);s=Math.max(Math.min(s,20),0),o=t.toFixed(s)}else o="0";return o},logarithmic:function(t,e,n){var a=t/Math.pow(10,Math.floor(i.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===e||e===n.length-1?t.toExponential():""}}}},{45:45}],35:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._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:r.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:r.noop,beforeBody:r.noop,beforeLabel:r.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),n+=t.yLabel},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:r.noop,afterBody:r.noop,beforeFooter:r.noop,footer:r.noop,afterFooter:r.noop}}}),e.exports=function(t){function e(t,e){var n=r.color(t);return n.alpha(e*n.alpha()).rgbaString()}function n(t,e){return e&&(r.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function o(t){var e=t._xScale,n=t._yScale||t._scale,i=t._index,a=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,a):"",yLabel:n?n.getLabelForIndex(i,a):"",index:i,datasetIndex:a,x:t._model.x,y:t._model.y}}function s(t){var e=i.global,n=r.valueOrDefault;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,bodyFontColor:t.bodyFontColor,_bodyFontFamily:n(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:n(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:n(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:n(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:n(t.titleFontStyle,e.defaultFontStyle),titleFontSize:n(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:n(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:n(t.footerFontStyle,e.defaultFontStyle),footerFontSize:n(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 l(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,o=e.body,s=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);s+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=l*d,i+=l?(l-1)*e.titleSpacing:0,i+=l?e.titleMarginBottom:0,i+=s*c,i+=s?(s-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,n.measureText(t).width+f)};return n.font=r.fontString(d,e._titleFontStyle,e._titleFontFamily),r.each(e.title,g),n.font=r.fontString(c,e._bodyFontStyle,e._bodyFontFamily),r.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,r.each(o,function(t){r.each(t.before,g),r.each(t.lines,g),r.each(t.after,g)}),f=0,n.font=r.fontString(h,e._footerFontStyle,e._footerFontFamily),r.each(e.footer,g),a+=2*e.xPadding,{width:a,height:i}}function u(t,e){var n=t._model,i=t._chart,a=t._chart.chartArea,r="center",o="center";n.y<e.height?o="top":n.y>i.height-e.height&&(o="bottom");var s,l,u,d,c,h=(a.left+a.right)/2,f=(a.top+a.bottom)/2;"center"===o?(s=function(t){return t<=h},l=function(t){return t>h}):(s=function(t){return t<=e.width/2},l=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return t<=f?"top":"bottom"},s(n.x)?(r="left",u(n.x)&&(r="center",o=c(n.y))):l(n.x)&&(r="right",d(n.x)&&(r="center",o=c(n.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:r,yAlign:g.yAlign?g.yAlign:o}}function d(t,e,n){var i=t.x,a=t.y,r=t.caretSize,o=t.caretPadding,s=t.cornerRadius,l=n.xAlign,u=n.yAlign,d=r+o,c=s+o;return"right"===l?i-=e.width:"center"===l&&(i-=e.width/2),"top"===u?a+=d:a-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===l?i+=d:"right"===l&&(i-=d):"left"===l?i-=c:"right"===l&&(i+=c),{x:i,y:a}}t.Tooltip=a.extend({initialize:function(){this._model=s(this._options)},getTitle:function(){var t=this,e=t._options.callbacks,i=e.beforeTitle.apply(t,arguments),a=e.title.apply(t,arguments),r=e.afterTitle.apply(t,arguments),o=[];return o=n(o,i),o=n(o,a),o=n(o,r)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return r.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var i=this,a=i._options.callbacks,o=[];return r.each(t,function(t){var r={before:[],lines:[],after:[]};n(r.before,a.beforeLabel.call(i,t,e)),n(r.lines,a.label.call(i,t,e)),n(r.after,a.afterLabel.call(i,t,e)),o.push(r)}),o},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return r.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,e=t._options.callbacks,i=e.beforeFooter.apply(t,arguments),a=e.footer.apply(t,arguments),r=e.afterFooter.apply(t,arguments),o=[];return o=n(o,i),o=n(o,a),o=n(o,r)},update:function(e){var n,i,a=this,c=a._options,h=a._model,f=a._model=s(c),g=a._active,m=a._data,p={xAlign:h.xAlign,yAlign:h.yAlign},v={x:h.x,y:h.y},y={width:h.width,height:h.height},b={x:h.caretX,y:h.caretY};if(g.length){f.opacity=1;var x=[],_=[];b=t.Tooltip.positioners[c.position](g,a._eventPosition);var k=[];for(n=0,i=g.length;n<i;++n)k.push(o(g[n]));c.filter&&(k=k.filter(function(t){return c.filter(t,m)})),c.itemSort&&(k=k.sort(function(t,e){return c.itemSort(t,e,m)})),r.each(k,function(t){x.push(c.callbacks.labelColor.call(a,t,a._chart)),_.push(c.callbacks.labelTextColor.call(a,t,a._chart))}),f.title=a.getTitle(k,m),f.beforeBody=a.getBeforeBody(k,m),f.body=a.getBody(k,m),f.afterBody=a.getAfterBody(k,m),f.footer=a.getFooter(k,m),f.x=Math.round(b.x),f.y=Math.round(b.y),f.caretPadding=c.caretPadding,f.labelColors=x,f.labelTextColors=_,f.dataPoints=k,v=d(f,y=l(this,f),p=u(this,y))}else f.opacity=0;return f.xAlign=p.xAlign,f.yAlign=p.yAlign,f.x=v.x,f.y=v.y,f.width=y.width,f.height=y.height,f.caretX=b.x,f.caretY=b.y,a._model=f,e&&c.custom&&c.custom.call(a,f),a},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,c=n.xAlign,h=n.yAlign,f=t.x,g=t.y,m=e.width,p=e.height;if("center"===h)s=g+p/2,"left"===c?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+m)+u,r=i,o=s-u,l=s+u);else if("left"===c?(i=(a=f+d+u)-u,r=a+u):"right"===c?(i=(a=f+m-d-u)-u,r=a+u):(i=(a=f+m/2)-u,r=a+u),"top"===h)s=(o=g)-u,l=o;else{s=(o=g+p)+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,n,i,a){var o=n.title;if(o.length){i.textAlign=n._titleAlign,i.textBaseline="top";var s=n.titleFontSize,l=n.titleSpacing;i.fillStyle=e(n.titleFontColor,a),i.font=r.fontString(s,n._titleFontStyle,n._titleFontFamily);var u,d;for(u=0,d=o.length;u<d;++u)i.fillText(o[u],t.x,t.y),t.y+=s+l,u+1===o.length&&(t.y+=n.titleMarginBottom-l)}},drawBody:function(t,n,i,a){var o=n.bodyFontSize,s=n.bodySpacing,l=n.body;i.textAlign=n._bodyAlign,i.textBaseline="top",i.font=r.fontString(o,n._bodyFontStyle,n._bodyFontFamily);var u=0,d=function(e){i.fillText(e,t.x+u,t.y),t.y+=o+s};r.each(n.beforeBody,d);var c=n.displayColors;u=c?o+2:0,r.each(l,function(s,l){r.each(s.before,d),r.each(s.lines,function(r){if(c){i.fillStyle=e(n.legendColorBackground,a),i.fillRect(t.x,t.y,o,o),i.lineWidth=1,i.strokeStyle=e(n.labelColors[l].borderColor,a),i.strokeRect(t.x,t.y,o,o),i.fillStyle=e(n.labelColors[l].backgroundColor,a),i.fillRect(t.x+1,t.y+1,o-2,o-2);var s=e(n.labelTextColors[l],a);i.fillStyle=s}d(r)}),r.each(s.after,d)}),u=0,r.each(n.afterBody,d),t.y-=s},drawFooter:function(t,n,i,a){var o=n.footer;o.length&&(t.y+=n.footerMarginTop,i.textAlign=n._footerAlign,i.textBaseline="top",i.fillStyle=e(n.footerFontColor,a),i.font=r.fontString(n.footerFontSize,n._footerFontStyle,n._footerFontFamily),r.each(o,function(e){i.fillText(e,t.x,t.y),t.y+=n.footerFontSize+n.footerSpacing}))},drawBackground:function(t,n,i,a,r){i.fillStyle=e(n.backgroundColor,r),i.strokeStyle=e(n.borderColor,r),i.lineWidth=n.borderWidth;var o=n.xAlign,s=n.yAlign,l=t.x,u=t.y,d=a.width,c=a.height,h=n.cornerRadius;i.beginPath(),i.moveTo(l+h,u),"top"===s&&this.drawCaret(t,a),i.lineTo(l+d-h,u),i.quadraticCurveTo(l+d,u,l+d,u+h),"center"===s&&"right"===o&&this.drawCaret(t,a),i.lineTo(l+d,u+c-h),i.quadraticCurveTo(l+d,u+c,l+d-h,u+c),"bottom"===s&&this.drawCaret(t,a),i.lineTo(l+h,u+c),i.quadraticCurveTo(l,u+c,l,u+c-h),"center"===s&&"left"===o&&this.drawCaret(t,a),i.lineTo(l,u+h),i.quadraticCurveTo(l,u,l+h,u),i.closePath(),i.fill(),n.borderWidth>0&&i.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&&(this.drawBackground(i,e,t,n,a),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,a),this.drawBody(i,e,t,a),this.drawFooter(i,e,t,a))}},handleEvent:function(t){var e=this,n=e._options,i=!1;if(e._lastActive=e._lastActive||[],"mouseout"===t.type?e._active=[]:e._active=e._chart.getElementsAtEventForMode(t,n.mode,n),!(i=!r.arrayEquals(e._active,e._lastActive)))return!1;if(e._lastActive=e._active,n.enabled||n.custom){e._eventPosition={x:t.x,y:t.y};var a=e._model;e.update(!0),e.pivot(),i|=a.x!==e._model.x||a.y!==e._model.y}return i}}),t.Tooltip.positioners={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:Math.round(i/r),y:Math.round(a/r)}},nearest:function(t,e){var n,i,a,o=e.x,s=e.y,l=Number.POSITIVE_INFINITY;for(n=0,i=t.length;n<i;++n){var u=t[n];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=r.distanceBetweenPoints(e,d);c<l&&(l=c,a=u)}}if(a){var h=a.tooltipPosition();o=h.x,s=h.y}return{x:o,y:s}}}}},{25:25,26:26,45:45}],36:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{elements:{arc:{backgroundColor:i.global.defaultColor,borderColor:"#fff",borderWidth:2}}}),e.exports=a.extend({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=r.getAngleFromPoint(n,{x:t,y:e}),a=i.angle,o=i.distance,s=n.startAngle,l=n.endAngle;l<s;)l+=2*Math.PI;for(;a>l;)a-=2*Math.PI;for(;a<s;)a+=2*Math.PI;var u=a>=s&&a<=l,d=o>=n.innerRadius&&o<=n.outerRadius;return u&&d}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=this._chart.ctx,e=this._view,n=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,n,i),t.arc(e.x,e.y,e.innerRadius,i,n,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{25:25,26:26,45:45}],37:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45),o=i.global;i._set("global",{elements:{line:{tension:.4,backgroundColor:o.defaultColor,borderWidth:3,borderColor:o.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,n,i,a=this,s=a._view,l=a._chart.ctx,u=s.spanGaps,d=a._children.slice(),c=o.elements.line,h=-1;for(a._loop&&d.length&&d.push(d[0]),l.save(),l.lineCap=s.borderCapStyle||c.borderCapStyle,l.setLineDash&&l.setLineDash(s.borderDash||c.borderDash),l.lineDashOffset=s.borderDashOffset||c.borderDashOffset,l.lineJoin=s.borderJoinStyle||c.borderJoinStyle,l.lineWidth=s.borderWidth||c.borderWidth,l.strokeStyle=s.borderColor||o.defaultColor,l.beginPath(),h=-1,t=0;t<d.length;++t)e=d[t],n=r.previousItem(d,t),i=e._view,0===t?i.skip||(l.moveTo(i.x,i.y),h=t):(n=-1===h?n:d[h],i.skip||(h!==t-1&&!u||-1===h?l.moveTo(i.x,i.y):r.canvas.lineTo(l,n._view,e._view),h=t));l.stroke(),l.restore()}})},{25:25,26:26,45:45}],38:[function(t,e,n){"use strict";function i(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2)}var a=t(25),r=t(26),o=t(45),s=a.global.defaultColor;a._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:s,borderColor:s,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}}),e.exports=r.extend({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:i,inXRange:i,inYRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.y,2)<Math.pow(e.radius+e.hitRadius,2)},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._model,i=this._chart.ctx,r=e.pointStyle,l=e.radius,u=e.x,d=e.y,c=o.color,h=0;e.skip||(i.strokeStyle=e.borderColor||s,i.lineWidth=o.valueOrDefault(e.borderWidth,a.global.elements.point.borderWidth),i.fillStyle=e.backgroundColor||s,void 0!==t&&(n.x<t.left||1.01*t.right<n.x||n.y<t.top||1.01*t.bottom<n.y)&&(n.x<t.left?h=(u-n.x)/(t.left-n.x):1.01*t.right<n.x?h=(n.x-u)/(n.x-t.right):n.y<t.top?h=(d-n.y)/(t.top-n.y):1.01*t.bottom<n.y&&(h=(n.y-d)/(n.y-t.bottom)),h=Math.round(100*h)/100,i.strokeStyle=c(i.strokeStyle).alpha(h).rgbString(),i.fillStyle=c(i.fillStyle).alpha(h).rgbString()),o.canvas.drawPoint(i,r,l,u,d))}})},{25:25,26:26,45:45}],39:[function(t,e,n){"use strict";function i(t){return void 0!==t._view.width}function a(t){var e,n,a,r,o=t._view;if(i(t)){var s=o.width/2;e=o.x-s,n=o.x+s,a=Math.min(o.y,o.base),r=Math.max(o.y,o.base)}else{var l=o.height/2;e=Math.min(o.x,o.base),n=Math.max(o.x,o.base),a=o.y-l,r=o.y+l}return{left:e,top:a,right:n,bottom:r}}var r=t(25),o=t(26);r._set("global",{elements:{rectangle:{backgroundColor:r.global.defaultColor,borderColor:r.global.defaultColor,borderSkipped:"bottom",borderWidth:0}}}),e.exports=o.extend({draw:function(){function t(t){return v[(y+t)%4]}var e,n,i,a,r,o,s,l=this._chart.ctx,u=this._view,d=u.borderWidth;if(u.horizontal?(e=u.base,n=u.x,i=u.y-u.height/2,a=u.y+u.height/2,r=n>e?1:-1,o=1,s=u.borderSkipped||"left"):(e=u.x-u.width/2,n=u.x+u.width/2,i=u.y,r=1,o=(a=u.base)>i?1:-1,s=u.borderSkipped||"bottom"),d){var c=Math.min(Math.abs(e-n),Math.abs(i-a)),h=(d=d>c?c:d)/2,f=e+("left"!==s?h*r:0),g=n+("right"!==s?-h*r:0),m=i+("top"!==s?h*o:0),p=a+("bottom"!==s?-h*o:0);f!==g&&(i=m,a=p),m!==p&&(e=f,n=g)}l.beginPath(),l.fillStyle=u.backgroundColor,l.strokeStyle=u.borderColor,l.lineWidth=d;var v=[[e,a],[e,i],[n,i],[n,a]],y=["bottom","left","top","right"].indexOf(s,0);-1===y&&(y=0);var b=t(0);l.moveTo(b[0],b[1]);for(var x=1;x<4;x++)b=t(x),l.lineTo(b[0],b[1]);l.fill(),d&&l.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var n=!1;if(this._view){var i=a(this);n=t>=i.left&&t<=i.right&&e>=i.top&&e<=i.bottom}return n},inLabelRange:function(t,e){var n=this;if(!n._view)return!1;var r=a(n);return i(n)?t>=r.left&&t<=r.right:e>=r.top&&e<=r.bottom},inXRange:function(t){var e=a(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=a(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,n=this._view;return i(this)?(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 t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{25:25,26:26}],40:[function(t,e,n){"use strict";e.exports={},e.exports.Arc=t(36),e.exports.Line=t(37),e.exports.Point=t(38),e.exports.Rectangle=t(39)},{36:36,37:37,38:38,39:39}],41:[function(t,e,n){"use strict";var i=t(42),n=e.exports={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,i/2),s=Math.min(r,a/2);t.moveTo(e+o,n),t.lineTo(e+i-o,n),t.quadraticCurveTo(e+i,n,e+i,n+s),t.lineTo(e+i,n+a-s),t.quadraticCurveTo(e+i,n+a,e+i-o,n+a),t.lineTo(e+o,n+a),t.quadraticCurveTo(e,n+a,e,n+a-s),t.lineTo(e,n+s),t.quadraticCurveTo(e,n,e+o,n)}else t.rect(e,n,i,a)},drawPoint:function(t,e,n,i,a){var r,o,s,l,u,d;if("object"!=typeof e||"[object HTMLImageElement]"!==(r=e.toString())&&"[object HTMLCanvasElement]"!==r){if(!(isNaN(n)||n<=0)){switch(e){default:t.beginPath(),t.arc(i,a,n,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),u=(o=3*n/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(i-o/2,a+u/3),t.lineTo(i+o/2,a+u/3),t.lineTo(i,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*n,t.beginPath(),t.fillRect(i-d,a-d,2*d,2*d),t.strokeRect(i-d,a-d,2*d,2*d);break;case"rectRounded":var c=n/Math.SQRT2,h=i-c,f=a-c,g=Math.SQRT2*n;t.beginPath(),this.roundedRect(t,h,f,g,g,n/2),t.closePath(),t.fill();break;case"rectRot":d=1/Math.SQRT2*n,t.beginPath(),t.moveTo(i-d,a),t.lineTo(i,a+d),t.lineTo(i+d,a),t.lineTo(i,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(i,a+n),t.lineTo(i,a-n),t.moveTo(i-n,a),t.lineTo(i+n,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*n,l=Math.sin(Math.PI/4)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i-s,a+l),t.lineTo(i+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(i,a+n),t.lineTo(i,a-n),t.moveTo(i-n,a),t.lineTo(i+n,a),s=Math.cos(Math.PI/4)*n,l=Math.sin(Math.PI/4)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i-s,a+l),t.lineTo(i+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(i-n,a),t.lineTo(i+n,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(i,a),t.lineTo(i+n,a),t.closePath()}t.stroke()}}else t.drawImage(e,i-e.width/2,a-e.height/2,e.width,e.height)},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){if(n.steppedLine)return"after"===n.steppedLine&&!i||"after"!==n.steppedLine&&i?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y),void t.lineTo(n.x,n.y);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)}};i.clear=n.clear,i.drawRoundedRectangle=function(t){t.beginPath(),n.roundedRect.apply(n,arguments),t.closePath()}},{42:42}],42:[function(t,e,n){"use strict";var i={noop:function(){},uid:function(){var t=0;return function(){return t++}}(),isNullOrUndef:function(t){return null===t||void 0===t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,n){return i.valueOrDefault(i.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,a){var r,o,s;if(i.isArray(t))if(o=t.length,a)for(r=o-1;r>=0;r--)e.call(n,t[r],r);else for(r=0;r<o;r++)e.call(n,t[r],r);else if(i.isObject(t))for(o=(s=Object.keys(t)).length,r=0;r<o;r++)e.call(n,t[s[r]],s[r])},arrayEquals:function(t,e){var n,a,r,o;if(!t||!e||t.length!==e.length)return!1;for(n=0,a=t.length;n<a;++n)if(r=t[n],o=e[n],r instanceof Array&&o instanceof Array){if(!i.arrayEquals(r,o))return!1}else if(r!==o)return!1;return!0},clone:function(t){if(i.isArray(t))return t.map(i.clone);if(i.isObject(t)){for(var e={},n=Object.keys(t),a=n.length,r=0;r<a;++r)e[n[r]]=i.clone(t[n[r]]);return e}return t},_merger:function(t,e,n,a){var r=e[t],o=n[t];i.isObject(r)&&i.isObject(o)?i.merge(r,o,a):e[t]=i.clone(o)},_mergerIf:function(t,e,n){var a=e[t],r=n[t];i.isObject(a)&&i.isObject(r)?i.mergeIf(a,r):e.hasOwnProperty(t)||(e[t]=i.clone(r))},merge:function(t,e,n){var a,r,o,s,l,u=i.isArray(e)?e:[e],d=u.length;if(!i.isObject(t))return t;for(a=(n=n||{}).merger||i._merger,r=0;r<d;++r)if(e=u[r],i.isObject(e))for(l=0,s=(o=Object.keys(e)).length;l<s;++l)a(o[l],t,e,n);return t},mergeIf:function(t,e){return i.merge(t,e,{merger:i._mergerIf})}};e.exports=i,i.callCallback=i.callback,i.indexOf=function(t,e,n){return Array.prototype.indexOf.call(t,e,n)},i.getValueOrDefault=i.valueOrDefault,i.getValueAtIndexOrDefault=i.valueAtIndexOrDefault},{}],43:[function(t,e,n){"use strict";var i=t(42),a={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-a.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*a.easeInBounce(2*t):.5*a.easeOutBounce(2*t-1)+.5}};e.exports={effects:a},i.easingEffects=a},{42:42}],44:[function(t,e,n){"use strict";var i=t(42);e.exports={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,a,r;return i.isObject(t)?(e=+t.top||0,n=+t.right||0,a=+t.bottom||0,r=+t.left||0):e=n=a=r=+t||0,{top:e,right:n,bottom:a,left:r,height:e+a,width:r+n}},resolve:function(t,e,n){var a,r,o;for(a=0,r=t.length;a<r;++a)if(void 0!==(o=t[a])&&(void 0!==e&&"function"==typeof o&&(o=o(e)),void 0!==n&&i.isArray(o)&&(o=o[n]),void 0!==o))return o}}},{42:42}],45:[function(t,e,n){"use strict";e.exports=t(42),e.exports.easing=t(43),e.exports.canvas=t(41),e.exports.options=t(44)},{41:41,42:42,43:43,44:44}],46:[function(t,e,n){e.exports={acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}}},{}],47:[function(t,e,n){"use strict";function i(t,e){var n=p.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}function a(t,e){var n=t.style,a=t.getAttribute("height"),r=t.getAttribute("width");if(t[v]={initial:{height:a,width:r,style:{display:n.display,height:n.height,width:n.width}}},n.display=n.display||"block",null===r||""===r){var o=i(t,"width");void 0!==o&&(t.width=o)}if(null===a||""===a)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var s=i(t,"height");void 0!==o&&(t.height=s)}return t}function r(t,e,n){t.addEventListener(e,n,w)}function o(t,e,n){t.removeEventListener(e,n,w)}function s(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 l(t,e){var n=k[t.type]||t.type,i=p.getRelativePosition(t,e);return s(n,e,i.x,i.y,t)}function u(t,e){var n=!1,i=[];return function(){i=Array.prototype.slice.call(arguments),e=e||this,n||(n=!0,p.requestAnimFrame.call(window,function(){n=!1,t.apply(e,i)}))}}function d(t){var e=document.createElement("div"),n=y+"size-monitor",i="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;";e.style.cssText=i,e.className=n,e.innerHTML='<div class="'+n+'-expand" style="'+i+'"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="'+n+'-shrink" style="'+i+'"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div>';var a=e.childNodes[0],o=e.childNodes[1];e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,o.scrollLeft=1e6,o.scrollTop=1e6};var s=function(){e._reset(),t()};return r(a,"scroll",s.bind(a,"expand")),r(o,"scroll",s.bind(o,"shrink")),e}function c(t,e){var n=(t[v]||(t[v]={})).renderProxy=function(t){t.animationName===x&&e()};p.each(_,function(e){r(t,e,n)}),t.classList.add(b)}function h(t){var e=t[v]||{},n=e.renderProxy;n&&(p.each(_,function(e){o(t,e,n)}),delete e.renderProxy),t.classList.remove(b)}function f(t,e,n){var i=t[v]||(t[v]={}),a=i.resizer=d(u(function(){if(i.resizer)return e(s("resize",n))}));c(t,function(){if(i.resizer){var e=t.parentNode;e&&e!==a.parentNode&&e.insertBefore(a,e.firstChild),a._reset()}})}function g(t){var e=t[v]||{},n=e.resizer;delete e.resizer,h(t),n&&n.parentNode&&n.parentNode.removeChild(n)}function m(t,e){var n=t._style||document.createElement("style");t._style||(t._style=n,e="/* Chart.js */\n"+e,n.setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(n)),n.appendChild(document.createTextNode(e))}var p=t(45),v="$chartjs",y="chartjs-",b=y+"render-monitor",x=y+"render-animation",_=["animationstart","webkitAnimationStart"],k={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},w=!!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};e.exports={_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,initialize:function(){var t="from{opacity:0.99}to{opacity:1}";m(this,"@-webkit-keyframes "+x+"{"+t+"}@keyframes "+x+"{"+t+"}."+b+"{-webkit-animation:"+x+" 0.001s;animation:"+x+" 0.001s;}")},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?(a(t,e),n):null},releaseContext:function(t){var e=t.canvas;if(e[v]){var n=e[v].initial;["height","width"].forEach(function(t){var i=n[t];p.isNullOrUndef(i)?e.removeAttribute(t):e.setAttribute(t,i)}),p.each(n.style||{},function(t,n){e.style[n]=t}),e.width=e.width,delete e[v]}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=n[v]||(n[v]={});r(i,e,(a.proxies||(a.proxies={}))[t.id+"_"+e]=function(e){n(l(e,t))})}else f(i,n,t)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=((n[v]||{}).proxies||{})[t.id+"_"+e];a&&o(i,e,a)}else g(i)}},p.addEvent=r,p.removeEvent=o},{45:45}],48:[function(t,e,n){"use strict";var i=t(45),a=t(46),r=t(47),o=r._enabled?r:a;e.exports=i.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},o)},{45:45,46:46,47:47}],49:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("global",{plugins:{filler:{propagate:!0}}}),e.exports=function(){function t(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 e(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.getBasePosition?r=i.getBasePosition():i.getBasePixel&&(r=i.getBasePixel()),void 0!==r&&null!==r){if(void 0!==r.x&&void 0!==r.y)return r;if("number"==typeof r&&isFinite(r))return e=i.isHorizontal(),{x:e?r:null,y:e?null:r}}return null}function n(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 o(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),d[n](t))}function s(t){return t&&!t.skip}function l(t,e,n,i,a){var o;if(i&&a){for(t.moveTo(e[0].x,e[0].y),o=1;o<i;++o)r.canvas.lineTo(t,e[o-1],e[o]);for(t.lineTo(n[a-1].x,n[a-1].y),o=a-1;o>0;--o)r.canvas.lineTo(t,n[o],n[o-1],!0)}}function u(t,e,n,i,a,r){var o,u,d,c,h,f,g,m=e.length,p=i.spanGaps,v=[],y=[],b=0,x=0;for(t.beginPath(),o=0,u=m+!!r;o<u;++o)h=n(c=e[d=o%m]._view,d,i),f=s(c),g=s(h),f&&g?(b=v.push(c),x=y.push(h)):b&&x&&(p?(f&&v.push(c),g&&y.push(h)):(l(t,v,y,b,x),b=x=0,v=[],y=[]));l(t,v,y,b,x),t.closePath(),t.fillStyle=a,t.fill()}var d={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 function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};return{id:"filler",afterDatasetsUpdate:function(i,r){var s,l,u,d,c=(i.data.datasets||[]).length,h=r.propagate,f=[];for(l=0;l<c;++l)d=null,(u=(s=i.getDatasetMeta(l)).dataset)&&u._model&&u instanceof a.Line&&(d={visible:i.isDatasetVisible(l),fill:t(u,l,c),chart:i,el:u}),s.$filler=d,f.push(d);for(l=0;l<c;++l)(d=f[l])&&(d.fill=n(f,l,h),d.boundary=e(d),d.mapper=o(d))},beforeDatasetDraw:function(t,e){var n=e.meta.$filler;if(n){var a=t.ctx,o=n.el,s=o._view,l=o._children||[],d=n.mapper,c=s.backgroundColor||i.global.defaultColor;d&&c&&l.length&&(r.canvas.clipArea(a,t.chartArea),u(a,l,d,s,c,o._loop),r.canvas.unclipArea(a))}}}}},{25:25,40:40,45:45}],50:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{legend:{display:!0,position:"top",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,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return r.isArray(e.datasets)?e.datasets.map(function(e,n){return{text:e.label,fillStyle:r.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(n),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:n}},this):[]}}},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var n=0;n<t.data.datasets.length;n++)e.push('<li><span style="background-color:'+t.data.datasets[n].backgroundColor+'"></span>'),t.data.datasets[n].label&&e.push(t.data.datasets[n].label),e.push("</li>");return e.push("</ul>"),e.join("")}}),e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}function n(e,n){var i=new t.Legend({ctx:e.ctx,options:n,chart:e});o.configure(e,i,n),o.addBox(e,i),e.legend=i}var o=t.layoutService,s=r.noop;return t.Legend=a.extend({initialize:function(t){r.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:s,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:s,beforeSetDimensions:s,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:s,beforeBuildLabels:s,buildLabels:function(){var t=this,e=t.options.labels||{},n=r.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:s,beforeFit:s,fit:function(){var t=this,n=t.options,a=n.labels,o=n.display,s=t.ctx,l=i.global,u=r.valueOrDefault,d=u(a.fontSize,l.defaultFontSize),c=u(a.fontStyle,l.defaultFontStyle),h=u(a.fontFamily,l.defaultFontFamily),f=r.fontString(d,c,h),g=t.legendHitBoxes=[],m=t.minSize,p=t.isHorizontal();if(p?(m.width=t.maxWidth,m.height=o?10:0):(m.width=o?10:0,m.height=t.maxHeight),o)if(s.font=f,p){var v=t.lineWidths=[0],y=t.legendItems.length?d+a.padding:0;s.textAlign="left",s.textBaseline="top",r.each(t.legendItems,function(n,i){var r=e(a,d)+d/2+s.measureText(n.text).width;v[v.length-1]+r+a.padding>=t.width&&(y+=d+a.padding,v[v.length]=t.left),g[i]={left:0,top:0,width:r,height:d},v[v.length-1]+=r+a.padding}),m.height+=y}else{var b=a.padding,x=t.columnWidths=[],_=a.padding,k=0,w=0,M=d+b;r.each(t.legendItems,function(t,n){var i=e(a,d)+d/2+s.measureText(t.text).width;w+M>m.height&&(_+=k+a.padding,x.push(k),k=0,w=0),k=Math.max(k,i),w+=M,g[n]={left:0,top:0,width:i,height:d}}),_+=k,x.push(k),m.width+=_}t.width=m.width,t.height=m.height},afterFit:s,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,n=t.options,a=n.labels,o=i.global,s=o.elements.line,l=t.width,u=t.lineWidths;if(n.display){var d,c=t.ctx,h=r.valueOrDefault,f=h(a.fontColor,o.defaultFontColor),g=h(a.fontSize,o.defaultFontSize),m=h(a.fontStyle,o.defaultFontStyle),p=h(a.fontFamily,o.defaultFontFamily),v=r.fontString(g,m,p);c.textAlign="left",c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var y=e(a,g),b=t.legendHitBoxes,x=function(t,e,i){if(!(isNaN(y)||y<=0)){c.save(),c.fillStyle=h(i.fillStyle,o.defaultColor),c.lineCap=h(i.lineCap,s.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,s.borderDashOffset),c.lineJoin=h(i.lineJoin,s.borderJoinStyle),c.lineWidth=h(i.lineWidth,s.borderWidth),c.strokeStyle=h(i.strokeStyle,o.defaultColor);var a=0===h(i.lineWidth,s.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,s.borderDash)),n.labels&&n.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=t+u,f=e+u;r.canvas.drawPoint(c,i.pointStyle,l,d,f)}else a||c.strokeRect(t,e,y,g),c.fillRect(t,e,y,g);c.restore()}},_=function(t,e,n,i){var a=g/2,r=y+a+t,o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(r+i,o),c.stroke())},k=t.isHorizontal();d=k?{x:t.left+(l-u[0])/2,y:t.top+a.padding,line:0}:{x:t.left+a.padding,y:t.top+a.padding,line:0};var w=g+a.padding;r.each(t.legendItems,function(e,n){var i=c.measureText(e.text).width,r=y+g/2+i,o=d.x,s=d.y;k?o+r>=l&&(s=d.y+=w,d.line++,o=d.x=t.left+(l-u[d.line])/2):s+w>t.bottom&&(o=d.x=o+t.columnWidths[d.line]+a.padding,s=d.y=t.top+a.padding,d.line++),x(o,s,e),b[n].left=o,b[n].top=s,_(o,s,e,i),k?d.x+=r+a.padding:d.y+=w})}},handleEvent:function(t){var e=this,n=e.options,i="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===i){if(!n.onHover)return}else{if("click"!==i)return;if(!n.onClick)return}var r=t.x,o=t.y;if(r>=e.left&&r<=e.right&&o>=e.top&&o<=e.bottom)for(var s=e.legendHitBoxes,l=0;l<s.length;++l){var u=s[l];if(r>=u.left&&r<=u.left+u.width&&o>=u.top&&o<=u.top+u.height){if("click"===i){n.onClick.call(e,t.native,e.legendItems[l]),a=!0;break}if("mousemove"===i){n.onHover.call(e,t.native,e.legendItems[l]),a=!0;break}}}return a}}),{id:"legend",beforeInit:function(t){var e=t.options.legend;e&&n(t,e)},beforeUpdate:function(t){var e=t.options.legend,a=t.legend;e?(r.mergeIf(e,i.global.legend),a?(o.configure(t,a,e),a.options=e):n(t,e)):a&&(o.removeBox(t,a),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}}}},{25:25,26:26,45:45}],51:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}}),e.exports=function(t){function e(e,i){var a=new t.Title({ctx:e.ctx,options:i,chart:e});n.configure(e,a,i),n.addBox(e,a),e.titleBlock=a}var n=t.layoutService,o=r.noop;return t.Title=a.extend({initialize:function(t){var e=this;r.extend(e,t),e.legendHitBoxes=[]},beforeUpdate:o,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:o,beforeSetDimensions:o,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:o,beforeBuildLabels:o,buildLabels:o,afterBuildLabels:o,beforeFit:o,fit:function(){var t=this,e=r.valueOrDefault,n=t.options,a=n.display,o=e(n.fontSize,i.global.defaultFontSize),s=t.minSize,l=r.isArray(n.text)?n.text.length:1,u=r.options.toLineHeight(n.lineHeight,o),d=a?l*u+2*n.padding:0;t.isHorizontal()?(s.width=t.maxWidth,s.height=d):(s.width=d,s.height=t.maxHeight),t.width=s.width,t.height=s.height},afterFit:o,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=r.valueOrDefault,a=t.options,o=i.global;if(a.display){var s,l,u,d=n(a.fontSize,o.defaultFontSize),c=n(a.fontStyle,o.defaultFontStyle),h=n(a.fontFamily,o.defaultFontFamily),f=r.fontString(d,c,h),g=r.options.toLineHeight(a.lineHeight,d),m=g/2+a.padding,p=0,v=t.top,y=t.left,b=t.bottom,x=t.right;e.fillStyle=n(a.fontColor,o.defaultFontColor),e.font=f,t.isHorizontal()?(l=y+(x-y)/2,u=v+m,s=x-y):(l="left"===a.position?y+m:x-m,u=v+(b-v)/2,s=b-v,p=Math.PI*("left"===a.position?-.5:.5)),e.save(),e.translate(l,u),e.rotate(p),e.textAlign="center",e.textBaseline="middle";var _=a.text;if(r.isArray(_))for(var k=0,w=0;w<_.length;++w)e.fillText(_[w],0,k,s),k+=g;else e.fillText(_,0,0,s);e.restore()}}}),{id:"title",beforeInit:function(t){var n=t.options.title;n&&e(t,n)},beforeUpdate:function(a){var o=a.options.title,s=a.titleBlock;o?(r.mergeIf(o,i.global.title),s?(n.configure(a,s,o),s.options=o):e(a,o)):s&&(t.layoutService.removeBox(a,s),delete a.titleBlock)}}}},{25:25,26:26,45:45}],52:[function(t,e,n){"use strict";e.exports=function(t){var e={position:"bottom"},n=t.Scale.extend({getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,e=t.getLabels();t.minIndex=0,t.maxIndex=e.length-1;var n;void 0!==t.options.ticks.min&&(n=e.indexOf(t.options.ticks.min),t.minIndex=-1!==n?n:t.minIndex),void 0!==t.options.ticks.max&&(n=e.indexOf(t.options.ticks.max),t.maxIndex=-1!==n?n:t.maxIndex),t.min=e[t.minIndex],t.max=e[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.isHorizontal();return i.yLabels&&!a?n.getRightValue(i.datasets[e].data[t]):n.ticks[t-n.minIndex]},getPixelForValue:function(t,e){var n,i=this,a=i.options.offset,r=Math.max(i.maxIndex+1-i.minIndex-(a?0:1),1);if(void 0!==t&&null!==t&&(n=i.isHorizontal()?t.x:t.y),void 0!==n||void 0!==t&&isNaN(e)){var o=i.getLabels();t=n||t;var s=o.indexOf(t);e=-1!==s?s:e}if(i.isHorizontal()){var l=i.width/r,u=l*(e-i.minIndex);return a&&(u+=l/2),i.left+Math.round(u)}var d=i.height/r,c=d*(e-i.minIndex);return a&&(c+=d/2),i.top+Math.round(c)},getPixelForTick:function(t){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null)},getValueForPixel:function(t){var e=this,n=e.options.offset,i=Math.max(e._ticks.length-(n?0:1),1),a=e.isHorizontal(),r=(a?e.width:e.height)/i;return t-=a?e.left:e.top,n&&(t-=r/2),(t<=0?0:Math.round(t/r))+e.minIndex},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",n,e)}},{}],53:[function(t,e,n){"use strict";var i=t(25),a=t(45),r=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:r.formatters.linear}},n=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return o?t.xAxisID===e.id:t.yAxisID===e.id}var e=this,n=e.options,i=e.chart,r=i.data.datasets,o=e.isHorizontal();e.min=null,e.max=null;var s=n.stacked;if(void 0===s&&a.each(r,function(e,n){if(!s){var a=i.getDatasetMeta(n);i.isDatasetVisible(n)&&t(a)&&void 0!==a.stack&&(s=!0)}}),n.stacked||s){var l={};a.each(r,function(r,o){var s=i.getDatasetMeta(o),u=[s.type,void 0===n.stacked&&void 0===s.stack?o:"",s.stack].join(".");void 0===l[u]&&(l[u]={positiveValues:[],negativeValues:[]});var d=l[u].positiveValues,c=l[u].negativeValues;i.isDatasetVisible(o)&&t(s)&&a.each(r.data,function(t,i){var a=+e.getRightValue(t);isNaN(a)||s.data[i].hidden||(d[i]=d[i]||0,c[i]=c[i]||0,n.relativePoints?d[i]=100:a<0?c[i]+=a:d[i]+=a)})}),a.each(l,function(t){var n=t.positiveValues.concat(t.negativeValues),i=a.min(n),r=a.max(n);e.min=null===e.min?i:Math.min(e.min,i),e.max=null===e.max?r:Math.max(e.max,r)})}else a.each(r,function(n,r){var o=i.getDatasetMeta(r);i.isDatasetVisible(r)&&t(o)&&a.each(n.data,function(t,n){var i=+e.getRightValue(t);isNaN(i)||o.data[n].hidden||(null===e.min?e.min=i:i<e.min&&(e.min=i),null===e.max?e.max=i:i>e.max&&(e.max=i))})});e.min=isFinite(e.min)&&!isNaN(e.min)?e.min:0,e.max=isFinite(e.max)&&!isNaN(e.max)?e.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this,n=e.options.ticks;if(e.isHorizontal())t=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(e.width/50));else{var r=a.valueOrDefault(n.fontSize,i.global.defaultFontSize);t=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(e.height/(2*r)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,n=this,i=n.start,a=+n.getRightValue(t),r=n.end-i;return n.isHorizontal()?(e=n.left+n.width/r*(a-i),Math.round(e)):(e=n.bottom-n.height/r*(a-i),Math.round(e))},getValueForPixel:function(t){var e=this,n=e.isHorizontal(),i=n?e.width:e.height,a=(n?t-e.left:e.bottom-t)/i;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",n,e)}},{25:25,34:34,45:45}],54:[function(t,e,n){"use strict";var i=t(45),a=t(34);e.exports=function(t){var e=i.noop;t.LinearScaleBase=t.Scale.extend({getRightValue:function(e){return"string"==typeof e?+e:t.Scale.prototype.getRightValue.call(this,e)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=i.sign(t.min),a=i.sign(t.max);n<0&&a<0?t.max=0:n>0&&a>0&&(t.min=0)}var r=void 0!==e.min||void 0!==e.suggestedMin,o=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)),r!==o&&t.min>=t.max&&(r?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),r={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,stepSize:i.valueOrDefault(e.fixedStepSize,e.stepSize)},o=t.ticks=a.generators.linear(r,t);t.handleDirectionalChanges(),t.max=i.max(o),t.min=i.min(o),e.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{34:34,45:45}],55:[function(t,e,n){"use strict";var i=t(45),a=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:a.formatters.logarithmic}},n=t.Scale.extend({determineDataLimits:function(){function t(t){return l?t.xAxisID===e.id:t.yAxisID===e.id}var e=this,n=e.options,a=n.ticks,r=e.chart,o=r.data.datasets,s=i.valueOrDefault,l=e.isHorizontal();e.min=null,e.max=null,e.minNotZero=null;var u=n.stacked;if(void 0===u&&i.each(o,function(e,n){if(!u){var i=r.getDatasetMeta(n);r.isDatasetVisible(n)&&t(i)&&void 0!==i.stack&&(u=!0)}}),n.stacked||u){var d={};i.each(o,function(a,o){var s=r.getDatasetMeta(o),l=[s.type,void 0===n.stacked&&void 0===s.stack?o:"",s.stack].join(".");r.isDatasetVisible(o)&&t(s)&&(void 0===d[l]&&(d[l]=[]),i.each(a.data,function(t,i){var a=d[l],r=+e.getRightValue(t);isNaN(r)||s.data[i].hidden||(a[i]=a[i]||0,n.relativePoints?a[i]=100:a[i]+=r)}))}),i.each(d,function(t){var n=i.min(t),a=i.max(t);e.min=null===e.min?n:Math.min(e.min,n),e.max=null===e.max?a:Math.max(e.max,a)})}else i.each(o,function(n,a){var o=r.getDatasetMeta(a);r.isDatasetVisible(a)&&t(o)&&i.each(n.data,function(t,n){var i=+e.getRightValue(t);isNaN(i)||o.data[n].hidden||(null===e.min?e.min=i:i<e.min&&(e.min=i),null===e.max?e.max=i:i>e.max&&(e.max=i),0!==i&&(null===e.minNotZero||i<e.minNotZero)&&(e.minNotZero=i))})});e.min=s(a.min,e.min),e.max=s(a.max,e.max),e.min===e.max&&(0!==e.min&&null!==e.min?(e.min=Math.pow(10,Math.floor(i.log10(e.min))-1),e.max=Math.pow(10,Math.floor(i.log10(e.max))+1)):(e.min=1,e.max=10))},buildTicks:function(){var t=this,e=t.options.ticks,n={min:e.min,max:e.max},r=t.ticks=a.generators.logarithmic(n,t);t.isHorizontal()||r.reverse(),t.max=i.max(r),t.min=i.min(r),e.reverse?(r.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var e,n,a,r=this,o=r.start,s=+r.getRightValue(t),l=r.options.ticks;return r.isHorizontal()?(a=i.log10(r.end)-i.log10(o),0===s?n=r.left:(e=r.width,n=r.left+e/a*(i.log10(s)-i.log10(o)))):(e=r.height,0!==o||l.reverse?0===r.end&&l.reverse?(a=i.log10(r.start)-i.log10(r.minNotZero),n=s===r.end?r.top:s===r.minNotZero?r.top+.02*e:r.top+.02*e+.98*e/a*(i.log10(s)-i.log10(r.minNotZero))):0===s?n=l.reverse?r.top:r.bottom:(a=i.log10(r.end)-i.log10(o),e=r.height,n=r.bottom-e/a*(i.log10(s)-i.log10(o))):(a=i.log10(r.end)-i.log10(r.minNotZero),n=s===o?r.bottom:s===r.minNotZero?r.bottom-.02*e:r.bottom-.02*e-.98*e/a*(i.log10(s)-i.log10(r.minNotZero)))),n},getValueForPixel:function(t){var e,n,a=this,r=i.log10(a.end)-i.log10(a.start);return a.isHorizontal()?(n=a.width,e=a.start*Math.pow(10,(t-a.left)*r/n)):(n=a.height,e=Math.pow(10,(a.bottom-t)*r/n)/a.start),e}});t.scaleService.registerScaleType("logarithmic",n,e)}},{34:34,45:45}],56:[function(t,e,n){"use strict";var i=t(25),a=t(45),r=t(34);e.exports=function(t){function e(t){var e=t.options;return e.angleLines.display||e.pointLabels.display?t.chart.data.labels.length:0}function n(t){var e=t.options.pointLabels,n=a.valueOrDefault(e.fontSize,p.defaultFontSize),i=a.valueOrDefault(e.fontStyle,p.defaultFontStyle),r=a.valueOrDefault(e.fontFamily,p.defaultFontFamily);return{size:n,style:i,family:r,font:a.fontString(n,i,r)}}function o(t,e,n){return a.isArray(n)?{w:a.longestText(t,t.font,n),h:n.length*e+1.5*(n.length-1)*e}:{w:t.measureText(n).width,h:e}}function s(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-5,end:e}:{start:e,end:e+n+5}}function l(t){var i,r,l,u=n(t),d=Math.min(t.height/2,t.width/2),c={r:t.width,l:0,t:t.height,b:0},h={};t.ctx.font=u.font,t._pointLabelSizes=[];var f=e(t);for(i=0;i<f;i++){l=t.getPointPosition(i,d),r=o(t.ctx,u.size,t.pointLabels[i]||""),t._pointLabelSizes[i]=r;var g=t.getIndexAngle(i),m=a.toDegrees(g)%360,p=s(m,l.x,r.w,0,180),v=s(m,l.y,r.h,90,270);p.start<c.l&&(c.l=p.start,h.l=g),p.end>c.r&&(c.r=p.end,h.r=g),v.start<c.t&&(c.t=v.start,h.t=g),v.end>c.b&&(c.b=v.end,h.b=g)}t.setReductions(d,c,h)}function u(t){var e=Math.min(t.height/2,t.width/2);t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0)}function d(t){return 0===t||180===t?"center":t<180?"left":"right"}function c(t,e,n,i){if(a.isArray(e))for(var r=n.y,o=1.5*i,s=0;s<e.length;++s)t.fillText(e[s],n.x,r),r+=o;else t.fillText(e,n.x,n.y)}function h(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function f(t){var i=t.ctx,r=a.valueOrDefault,o=t.options,s=o.angleLines,l=o.pointLabels;i.lineWidth=s.lineWidth,i.strokeStyle=s.color;var u=t.getDistanceFromCenterForValue(o.ticks.reverse?t.min:t.max),f=n(t);i.textBaseline="top";for(var g=e(t)-1;g>=0;g--){if(s.display){var m=t.getPointPosition(g,u);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(m.x,m.y),i.stroke(),i.closePath()}if(l.display){var v=t.getPointPosition(g,u+5),y=r(l.fontColor,p.defaultFontColor);i.font=f.font,i.fillStyle=y;var b=t.getIndexAngle(g),x=a.toDegrees(b);i.textAlign=d(x),h(x,t._pointLabelSizes[g],v),c(i,t.pointLabels[g]||"",v,f.size)}}}function g(t,n,i,r){var o=t.ctx;if(o.strokeStyle=a.valueAtIndexOrDefault(n.color,r-1),o.lineWidth=a.valueAtIndexOrDefault(n.lineWidth,r-1),t.options.gridLines.circular)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var s=e(t);if(0===s)return;o.beginPath();var l=t.getPointPosition(0,i);o.moveTo(l.x,l.y);for(var u=1;u<s;u++)l=t.getPointPosition(u,i),o.lineTo(l.x,l.y);o.closePath(),o.stroke()}}function m(t){return a.isNumber(t)?t:0}var p=i.global,v={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:r.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}},y=t.LinearScaleBase.extend({setDimensions:function(){var t=this,e=t.options,n=e.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var i=a.min([t.height,t.width]),r=a.valueOrDefault(n.fontSize,p.defaultFontSize);t.drawingArea=e.display?i/2-(r/2+n.backdropPaddingY):i/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;a.each(e.data.datasets,function(r,o){if(e.isDatasetVisible(o)){var s=e.getDatasetMeta(o);a.each(r.data,function(e,a){var r=+t.getRightValue(e);isNaN(r)||s.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()},getTickLimit:function(){var t=this.options.ticks,e=a.valueOrDefault(t.fontSize,p.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*e)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){this.options.pointLabels.display?l(this):u(this)},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,0)/Math.cos(n.b);a=m(a),r=m(r),o=m(o),s=m(s),i.drawingArea=Math.min(Math.round(t-(a+r)/2),Math.round(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-i-a.drawingArea;a.xCenter=Math.round((o+r)/2+a.left),a.yCenter=Math.round((s+l)/2+a.top)},getIndexAngle:function(t){return t*(2*Math.PI/e(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;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,i=n.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+n.xCenter,y:Math.round(Math.sin(i)*e)+n.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,n=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},draw:function(){var t=this,e=t.options,n=e.gridLines,i=e.ticks,r=a.valueOrDefault;if(e.display){var o=t.ctx,s=this.getIndexAngle(0),l=r(i.fontSize,p.defaultFontSize),u=r(i.fontStyle,p.defaultFontStyle),d=r(i.fontFamily,p.defaultFontFamily),c=a.fontString(l,u,d);a.each(t.ticks,function(e,a){if(a>0||i.reverse){var u=t.getDistanceFromCenterForValue(t.ticksAsNumbers[a]);if(n.display&&0!==a&&g(t,n,u,a),i.display){var d=r(i.fontColor,p.defaultFontColor);if(o.font=c,o.save(),o.translate(t.xCenter,t.yCenter),o.rotate(s),i.showLabelBackdrop){var h=o.measureText(e).width;o.fillStyle=i.backdropColor,o.fillRect(-h/2-i.backdropPaddingX,-u-l/2-i.backdropPaddingY,h+2*i.backdropPaddingX,l+2*i.backdropPaddingY)}o.textAlign="center",o.textBaseline="middle",o.fillStyle=d,o.fillText(e,0,-u),o.restore()}}}),(e.angleLines.display||e.pointLabels.display)&&f(t)}}});t.scaleService.registerScaleType("radialLinear",y,v)}},{25:25,34:34,45:45}],57:[function(t,e,n){"use strict";function i(t,e){return t-e}function a(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}function r(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}function o(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(i=o+s>>1,a=t[i-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}}function s(t,e,n,i){var a=o(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],s=a.lo?a.hi?a.hi:t[t.length-1]:t[1],l=s[e]-r[e],u=l?(n-r[e])/l:0,d=(s[i]-r[i])*u;return r[i]+d}function l(t,e){var n=e.parser,i=e.parser||e.format;return"function"==typeof n?n(t):"string"==typeof t&&"string"==typeof i?p(t,i):(t instanceof p||(t=p(t)),t.isValid()?t:"function"==typeof i?i(t):t)}function u(t,e){if(y.isNullOrUndef(t))return null;var n=e.options.time,i=l(e.getRightValue(t),n);return i.isValid()?(n.round&&i.startOf(n.round),i.valueOf()):null}function d(t,e,n,i){var a,r,o,s=e-t,l=_[n],u=l.size,d=l.steps;if(!d)return Math.ceil(s/((i||1)*u));for(a=0,r=d.length;a<r&&(o=d[a],!(Math.ceil(s/(u*o))<=i));++a);return o}function c(t,e,n,i){var a,r,o,s=k.length;for(a=k.indexOf(t);a<s-1;++a)if(r=_[k[a]],o=r.steps?r.steps[r.steps.length-1]:x,Math.ceil((n-e)/(o*r.size))<=i)return k[a];return k[s-1]}function h(t){for(var e=k.indexOf(t)+1,n=k.length;e<n;++e)if(_[k[e]].major)return k[e]}function f(t,e,n,i,a,r){var o,s=r.time,l=y.valueOrDefault(s.stepSize,s.unitStepSize),u="week"===n&&s.isoWeekday,c=r.ticks.major.enabled,h=_[n],f=p(t),g=p(e),m=[];for(l||(l=d(t,e,n,a)),u&&(f=f.isoWeekday(u),g=g.isoWeekday(u)),f=f.startOf(u?"day":n),(g=g.startOf(u?"day":n))<e&&g.add(1,n),o=p(f),c&&i&&!u&&!s.round&&(o.startOf(i),o.add(~~((f-o)/(h.size*l))*l,n));o<g;o.add(l,n))m.push(+o);return m.push(+o),m}function g(t,e,n,i,a){var r,o,l=0,u=0;return a.offset&&e.length&&(a.time.min||(r=e.length>1?e[1]:i,o=e[0],l=(s(t,"time",r,"pos")-s(t,"time",o,"pos"))/2),a.time.max||(r=e[e.length-1],o=e.length>1?e[e.length-2]:n,u=(s(t,"time",r,"pos")-s(t,"time",o,"pos"))/2)),{left:l,right:u}}function m(t,e){var n,i,a,r,o=[];for(n=0,i=t.length;n<i;++n)a=t[n],r=!!e&&a===+p(a).startOf(e),o.push({value:a,major:r});return o}var p=t(6);p="function"==typeof p?p:window.moment;var v=t(25),y=t(45),b=Number.MIN_SAFE_INTEGER||-9007199254740991,x=Number.MAX_SAFE_INTEGER||9007199254740991,_={millisecond:{major:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{major:!0,size:1e3,steps:[1,2,5,10,30]},minute:{major:!0,size:6e4,steps:[1,2,5,10,30]},hour:{major:!0,size:36e5,steps:[1,2,3,6,12]},day:{major:!0,size:864e5,steps:[1,2,5]},week:{major:!1,size:6048e5,steps:[1,2,3,4]},month:{major:!0,size:2628e6,steps:[1,2,3]},quarter:{major:!1,size:7884e6,steps:[1,2,3,4]},year:{major:!0,size:3154e7}},k=Object.keys(_);e.exports=function(t){var e={position:"bottom",distribution:"linear",bounds:"data",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{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"}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}},n=t.Scale.extend({initialize:function(){if(!p)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");this.mergeTicksOptions(),t.Scale.prototype.initialize.call(this)},update:function(){var e=this,n=e.options;return n.time&&n.time.format&&console.warn("options.time.format is deprecated and replaced by options.time.parser."),t.Scale.prototype.update.apply(e,arguments)},getRightValue:function(e){return e&&void 0!==e.t&&(e=e.t),t.Scale.prototype.getRightValue.call(this,e)},determineDataLimits:function(){var t,e,n,r,o,s,l=this,d=l.chart,c=l.options.time,h=u(c.min,l)||x,f=u(c.max,l)||b,g=[],m=[],v=[];for(t=0,n=d.data.labels.length;t<n;++t)v.push(u(d.data.labels[t],l));for(t=0,n=(d.data.datasets||[]).length;t<n;++t)if(d.isDatasetVisible(t))if(o=d.data.datasets[t].data,y.isObject(o[0]))for(m[t]=[],e=0,r=o.length;e<r;++e)s=u(o[e],l),g.push(s),m[t][e]=s;else g.push.apply(g,v),m[t]=v.slice(0);else m[t]=[];v.length&&(v=a(v).sort(i),h=Math.min(h,v[0]),f=Math.max(f,v[v.length-1])),g.length&&(g=a(g).sort(i),h=Math.min(h,g[0]),f=Math.max(f,g[g.length-1])),h=h===x?+p().startOf("day"):h,f=f===b?+p().endOf("day")+1:f,l.min=Math.min(h,f),l.max=Math.max(h+1,f),l._horizontal=l.isHorizontal(),l._table=[],l._timestamps={data:g,datasets:m,labels:v}},buildTicks:function(){var t,e,n,i=this,a=i.min,o=i.max,s=i.options,l=s.time,d=l.displayFormats,p=i.getLabelCapacity(a),v=l.unit||c(l.minUnit,a,o,p),y=h(v),b=[],x=[];switch(s.ticks.source){case"data":b=i._timestamps.data;break;case"labels":b=i._timestamps.labels;break;case"auto":default:b=f(a,o,v,y,p,s)}for("ticks"===s.bounds&&b.length&&(a=b[0],o=b[b.length-1]),a=u(l.min,i)||a,o=u(l.max,i)||o,t=0,e=b.length;t<e;++t)(n=b[t])>=a&&n<=o&&x.push(n);return i.min=a,i.max=o,i._unit=v,i._majorUnit=y,i._minorFormat=d[v],i._majorFormat=d[y],i._table=r(i._timestamps.data,a,o,s.distribution),i._offsets=g(i._table,x,a,o,s),m(x,y)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.options.time,r=i.labels&&t<i.labels.length?i.labels[t]:"",o=i.datasets[e].data[t];return y.isObject(o)&&(r=n.getRightValue(o)),a.tooltipFormat&&(r=l(r,a).format(a.tooltipFormat)),r},tickFormatFunction:function(t,e,n){var i=this,a=i.options,r=t.valueOf(),o=i._majorUnit,s=i._majorFormat,l=t.clone().startOf(i._majorUnit).valueOf(),u=a.ticks.major,d=u.enabled&&o&&s&&r===l,c=t.format(d?s:i._minorFormat),h=d?u:a.ticks.minor,f=y.valueOrDefault(h.callback,h.userCallback);return f?f(c,e,n):c},convertTicksToLabels:function(t){var e,n,i=[];for(e=0,n=t.length;e<n;++e)i.push(this.tickFormatFunction(p(t[e].value),e,t));return i},getPixelForOffset:function(t){var e=this,n=e._horizontal?e.width:e.height,i=e._horizontal?e.left:e.top,a=s(e._table,"time",t,"pos");return i+n*(e._offsets.left+a)/(e._offsets.left+1+e._offsets.right)},getPixelForValue:function(t,e,n){var i=this,a=null;if(void 0!==e&&void 0!==n&&(a=i._timestamps.datasets[n][e]),null===a&&(a=u(t,i)),null!==a)return i.getPixelForOffset(a)},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,n=e._horizontal?e.width:e.height,i=e._horizontal?e.left:e.top,a=(n?(t-i)/n:0)*(e._offsets.left+1+e._offsets.left)-e._offsets.right,r=s(e._table,"pos",a,"time");return p(r)},getLabelWidth:function(t){var e=this,n=e.options.ticks,i=e.ctx.measureText(t).width,a=y.toRadians(n.maxRotation),r=Math.cos(a),o=Math.sin(a);return i*r+y.valueOrDefault(n.fontSize,v.global.defaultFontSize)*o},getLabelCapacity:function(t){var e=this;e._minorFormat=e.options.time.displayFormats.millisecond;var n=e.tickFormatFunction(p(t),0,[]),i=e.getLabelWidth(n),a=e.isHorizontal()?e.width:e.height;return Math.floor(a/i)}});t.scaleService.registerScaleType("time",n,e)}},{25:25,45:45,6:6}]},{},[7])(7)});
|
|
|
|
|
|
|
|
|
|
|
|
1 |
/*!
|
2 |
+
* Chart.js v3.7.1
|
3 |
+
* https://www.chartjs.org
|
4 |
+
* (c) 2022 Chart.js Contributors
|
5 |
+
* Released under the MIT License
|
|
|
|
|
|
|
6 |
*/
|
7 |
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";const t="undefined"==typeof window?function(t){return t()}:window.requestAnimationFrame;function e(e,i,s){const n=s||(t=>Array.prototype.slice.call(t));let o=!1,a=[];return function(...s){a=n(s),o||(o=!0,t.call(window,(()=>{o=!1,e.apply(i,a)})))}}function i(t,e){let i;return function(...s){return e?(clearTimeout(i),i=setTimeout(t,e,s)):t.apply(this,s),e}}const s=t=>"start"===t?"left":"end"===t?"right":"center",n=(t,e,i)=>"start"===t?e:"end"===t?i:(e+i)/2,o=(t,e,i,s)=>t===(s?"left":"right")?i:"center"===t?(e+i)/2:e;var a=new class{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,s){const n=e.listeners[s],o=e.duration;n.forEach((s=>s({chart:t,initial:e.initial,numSteps:o,currentStep:Math.min(i-e.start,o)})))}_refresh(){this._request||(this._running=!0,this._request=t.call(window,(()=>{this._update(),this._request=null,this._running&&this._refresh()})))}_update(t=Date.now()){let e=0;this._charts.forEach(((i,s)=>{if(!i.running||!i.items.length)return;const n=i.items;let o,a=n.length-1,r=!1;for(;a>=0;--a)o=n[a],o._active?(o._total>i.duration&&(i.duration=o._total),o.tick(t),r=!0):(n[a]=n[n.length-1],n.pop());r&&(s.draw(),this._notify(s,i,t,"progress")),n.length||(i.running=!1,this._notify(s,i,t,"complete"),i.initial=!1),e+=n.length})),this._lastDate=t,0===e&&(this._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let s=i.length-1;for(;s>=0;--s)i[s].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}};
|
8 |
+
/*!
|
9 |
+
* @kurkle/color v0.1.9
|
10 |
+
* https://github.com/kurkle/color#readme
|
11 |
+
* (c) 2020 Jukka Kurkela
|
12 |
+
* Released under the MIT License
|
13 |
+
*/const r={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},l="0123456789ABCDEF",h=t=>l[15&t],c=t=>l[(240&t)>>4]+l[15&t],d=t=>(240&t)>>4==(15&t);function u(t){var e=function(t){return d(t.r)&&d(t.g)&&d(t.b)&&d(t.a)}(t)?h:c;return t?"#"+e(t.r)+e(t.g)+e(t.b)+(t.a<255?e(t.a):""):t}function f(t){return t+.5|0}const g=(t,e,i)=>Math.max(Math.min(t,i),e);function p(t){return g(f(2.55*t),0,255)}function m(t){return g(f(255*t),0,255)}function x(t){return g(f(t/2.55)/100,0,1)}function b(t){return g(f(100*t),0,100)}const _=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const y=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function v(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function w(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function M(t,e,i){const s=v(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function k(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=n===e?(i-s)/h+(i<s?6:0):n===i?(s-e)/h+2:(e-i)/h+4,r=60*r+.5),[0|r,l||0,a]}function S(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(m)}function P(t,e,i){return S(v,t,e,i)}function D(t){return(t%360+360)%360}function C(t){const e=y.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?p(+e[5]):m(+e[5]));const n=D(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return S(M,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return S(w,t,e,i)}(n,o,a):P(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const O={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg",D:"ights",R:"in",Q:"turquois",E:"hi",P:"ro",O:"al",N:"le",M:"de",L:"yello",F:"en",K:"ch",G:"arks",H:"ea",I:"ightg",J:"wh"},A={OiceXe:"f0f8ff",antiquewEte:"faebd7",aqua:"ffff",aquamarRe:"7fffd4",azuY:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"0",blanKedOmond:"ffebcd",Xe:"ff",XeviTet:"8a2be2",bPwn:"a52a2a",burlywood:"deb887",caMtXe:"5f9ea0",KartYuse:"7fff00",KocTate:"d2691e",cSO:"ff7f50",cSnflowerXe:"6495ed",cSnsilk:"fff8dc",crimson:"dc143c",cyan:"ffff",xXe:"8b",xcyan:"8b8b",xgTMnPd:"b8860b",xWay:"a9a9a9",xgYF:"6400",xgYy:"a9a9a9",xkhaki:"bdb76b",xmagFta:"8b008b",xTivegYF:"556b2f",xSange:"ff8c00",xScEd:"9932cc",xYd:"8b0000",xsOmon:"e9967a",xsHgYF:"8fbc8f",xUXe:"483d8b",xUWay:"2f4f4f",xUgYy:"2f4f4f",xQe:"ced1",xviTet:"9400d3",dAppRk:"ff1493",dApskyXe:"bfff",dimWay:"696969",dimgYy:"696969",dodgerXe:"1e90ff",fiYbrick:"b22222",flSOwEte:"fffaf0",foYstWAn:"228b22",fuKsia:"ff00ff",gaRsbSo:"dcdcdc",ghostwEte:"f8f8ff",gTd:"ffd700",gTMnPd:"daa520",Way:"808080",gYF:"8000",gYFLw:"adff2f",gYy:"808080",honeyMw:"f0fff0",hotpRk:"ff69b4",RdianYd:"cd5c5c",Rdigo:"4b0082",ivSy:"fffff0",khaki:"f0e68c",lavFMr:"e6e6fa",lavFMrXsh:"fff0f5",lawngYF:"7cfc00",NmoncEffon:"fffacd",ZXe:"add8e6",ZcSO:"f08080",Zcyan:"e0ffff",ZgTMnPdLw:"fafad2",ZWay:"d3d3d3",ZgYF:"90ee90",ZgYy:"d3d3d3",ZpRk:"ffb6c1",ZsOmon:"ffa07a",ZsHgYF:"20b2aa",ZskyXe:"87cefa",ZUWay:"778899",ZUgYy:"778899",ZstAlXe:"b0c4de",ZLw:"ffffe0",lime:"ff00",limegYF:"32cd32",lRF:"faf0e6",magFta:"ff00ff",maPon:"800000",VaquamarRe:"66cdaa",VXe:"cd",VScEd:"ba55d3",VpurpN:"9370db",VsHgYF:"3cb371",VUXe:"7b68ee",VsprRggYF:"fa9a",VQe:"48d1cc",VviTetYd:"c71585",midnightXe:"191970",mRtcYam:"f5fffa",mistyPse:"ffe4e1",moccasR:"ffe4b5",navajowEte:"ffdead",navy:"80",Tdlace:"fdf5e6",Tive:"808000",TivedBb:"6b8e23",Sange:"ffa500",SangeYd:"ff4500",ScEd:"da70d6",pOegTMnPd:"eee8aa",pOegYF:"98fb98",pOeQe:"afeeee",pOeviTetYd:"db7093",papayawEp:"ffefd5",pHKpuff:"ffdab9",peru:"cd853f",pRk:"ffc0cb",plum:"dda0dd",powMrXe:"b0e0e6",purpN:"800080",YbeccapurpN:"663399",Yd:"ff0000",Psybrown:"bc8f8f",PyOXe:"4169e1",saddNbPwn:"8b4513",sOmon:"fa8072",sandybPwn:"f4a460",sHgYF:"2e8b57",sHshell:"fff5ee",siFna:"a0522d",silver:"c0c0c0",skyXe:"87ceeb",UXe:"6a5acd",UWay:"708090",UgYy:"708090",snow:"fffafa",sprRggYF:"ff7f",stAlXe:"4682b4",tan:"d2b48c",teO:"8080",tEstN:"d8bfd8",tomato:"ff6347",Qe:"40e0d0",viTet:"ee82ee",JHt:"f5deb3",wEte:"ffffff",wEtesmoke:"f5f5f5",Lw:"ffff00",LwgYF:"9acd32"};let T;function L(t){T||(T=function(){const t={},e=Object.keys(A),i=Object.keys(O);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,O[o]);o=parseInt(A[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),T.transparent=[0,0,0,0]);const e=T[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}function R(t,e,i){if(t){let s=k(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=P(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function E(t,e){return t?Object.assign(e||{},t):t}function I(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=m(t[3]))):(e=E(t,{r:0,g:0,b:0,a:1})).a=m(e.a),e}function z(t){return"r"===t.charAt(0)?function(t){const e=_.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=255&(e[8]?p(t):255*t)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?p(i):i),s=255&(e[4]?p(s):s),n=255&(e[6]?p(n):n),{r:i,g:s,b:n,a:o}}}(t):C(t)}class F{constructor(t){if(t instanceof F)return t;const e=typeof t;let i;var s,n,o;"object"===e?i=I(t):"string"===e&&(o=(s=t).length,"#"===s[0]&&(4===o||5===o?n={r:255&17*r[s[1]],g:255&17*r[s[2]],b:255&17*r[s[3]],a:5===o?17*r[s[4]]:255}:7!==o&&9!==o||(n={r:r[s[1]]<<4|r[s[2]],g:r[s[3]]<<4|r[s[4]],b:r[s[5]]<<4|r[s[6]],a:9===o?r[s[7]]<<4|r[s[8]]:255})),i=n||L(t)||z(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=E(this._rgb);return t&&(t.a=x(t.a)),t}set rgb(t){this._rgb=I(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${x(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):this._rgb;var t}hexString(){return this._valid?u(this._rgb):this._rgb}hslString(){return this._valid?function(t){if(!t)return;const e=k(t),i=e[0],s=b(e[1]),n=b(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${x(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):this._rgb}mix(t,e){const i=this;if(t){const s=i.rgb,n=t.rgb;let o;const a=e===o?.5:e,r=2*a-1,l=s.a-n.a,h=((r*l==-1?r:(r+l)/(1+r*l))+1)/2;o=1-h,s.r=255&h*s.r+o*n.r+.5,s.g=255&h*s.g+o*n.g+.5,s.b=255&h*s.b+o*n.b+.5,s.a=a*s.a+(1-a)*n.a,i.rgb=s}return i}clone(){return new F(this.rgb)}alpha(t){return this._rgb.a=m(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=f(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return R(this._rgb,2,t),this}darken(t){return R(this._rgb,2,-t),this}saturate(t){return R(this._rgb,1,t),this}desaturate(t){return R(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=k(t);i[0]=D(i[0]+e),i=P(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function B(t){return new F(t)}const V=t=>t instanceof CanvasGradient||t instanceof CanvasPattern;function W(t){return V(t)?t:B(t)}function N(t){return V(t)?t:B(t).saturate(.5).darken(.1).hexString()}function H(){}const j=function(){let t=0;return function(){return t++}}();function $(t){return null==t}function Y(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)}function U(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}const X=t=>("number"==typeof t||t instanceof Number)&&isFinite(+t);function q(t,e){return X(t)?t:e}function K(t,e){return void 0===t?e:t}const G=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e,Z=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function J(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function Q(t,e,i,s){let n,o,a;if(Y(t))if(o=t.length,s)for(n=o-1;n>=0;n--)e.call(i,t[n],n);else for(n=0;n<o;n++)e.call(i,t[n],n);else if(U(t))for(a=Object.keys(t),o=a.length,n=0;n<o;n++)e.call(i,t[a[n]],a[n])}function tt(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function et(t){if(Y(t))return t.map(et);if(U(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=et(t[i[n]]);return e}return t}function it(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}function st(t,e,i,s){if(!it(t))return;const n=e[t],o=i[t];U(n)&&U(o)?nt(n,o,s):e[t]=et(o)}function nt(t,e,i){const s=Y(e)?e:[e],n=s.length;if(!U(t))return t;const o=(i=i||{}).merger||st;for(let a=0;a<n;++a){if(!U(e=s[a]))continue;const n=Object.keys(e);for(let s=0,a=n.length;s<a;++s)o(n[s],t,e,i)}return t}function ot(t,e){return nt(t,e,{merger:at})}function at(t,e,i){if(!it(t))return;const s=e[t],n=i[t];U(s)&&U(n)?ot(s,n):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=et(n))}function rt(t,e){const i=t.indexOf(".",e);return-1===i?t.length:i}function lt(t,e){if(""===e)return t;let i=0,s=rt(e,i);for(;t&&s>i;)t=t[e.substr(i,s-i)],i=s+1,s=rt(e,i);return t}function ht(t){return t.charAt(0).toUpperCase()+t.slice(1)}const ct=t=>void 0!==t,dt=t=>"function"==typeof t,ut=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function ft(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const gt=Object.create(null),pt=Object.create(null);function mt(t,e){if(!e)return t;const i=e.split(".");for(let e=0,s=i.length;e<s;++e){const s=i[e];t=t[s]||(t[s]=Object.create(null))}return t}function xt(t,e,i){return"string"==typeof e?nt(mt(t,e),i):nt(mt(t,""),e)}var bt=new class{constructor(t){this.animation=void 0,this.backgroundColor="rgba(0,0,0,0.1)",this.borderColor="rgba(0,0,0,0.1)",this.color="#666",this.datasets={},this.devicePixelRatio=t=>t.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>N(e.backgroundColor),this.hoverBorderColor=(t,e)=>N(e.borderColor),this.hoverColor=(t,e)=>N(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t)}set(t,e){return xt(this,t,e)}get(t){return mt(this,t)}describe(t,e){return xt(pt,t,e)}override(t,e){return xt(gt,t,e)}route(t,e,i,s){const n=mt(this,t),o=mt(this,i),a="_"+e;Object.defineProperties(n,{[a]:{value:n[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[a],e=o[s];return U(t)?Object.assign({},e,t):K(t,e)},set(t){this[a]=t}}})}}({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}});const _t=Math.PI,yt=2*_t,vt=yt+_t,wt=Number.POSITIVE_INFINITY,Mt=_t/180,kt=_t/2,St=_t/4,Pt=2*_t/3,Dt=Math.log10,Ct=Math.sign;function Ot(t){const e=Math.round(t);t=Lt(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(Dt(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function At(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function Tt(t){return!isNaN(parseFloat(t))&&isFinite(t)}function Lt(t,e,i){return Math.abs(t-e)<i}function Rt(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function Et(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function It(t){return t*(_t/180)}function zt(t){return t*(180/_t)}function Ft(t){if(!X(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function Bt(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*_t&&(o+=yt),{angle:o,distance:n}}function Vt(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function Wt(t,e){return(t-e+vt)%yt-_t}function Nt(t){return(t%yt+yt)%yt}function Ht(t,e,i,s){const n=Nt(t),o=Nt(e),a=Nt(i),r=Nt(o-n),l=Nt(a-n),h=Nt(n-o),c=Nt(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function jt(t,e,i){return Math.max(e,Math.min(i,t))}function $t(t){return jt(t,-32768,32767)}function Yt(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function Ut(t){return!t||$(t.size)||$(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function Xt(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function qt(t,e,i,s){let n=(s=s||{}).data=s.data||{},o=s.garbageCollect=s.garbageCollect||[];s.font!==e&&(n=s.data={},o=s.garbageCollect=[],s.font=e),t.save(),t.font=e;let a=0;const r=i.length;let l,h,c,d,u;for(l=0;l<r;l++)if(d=i[l],null!=d&&!0!==Y(d))a=Xt(t,n,o,a,d);else if(Y(d))for(h=0,c=d.length;h<c;h++)u=d[h],null==u||Y(u)||(a=Xt(t,n,o,a,u));t.restore();const f=o.length/2;if(f>i.length){for(l=0;l<f;l++)delete n[o[l]];o.splice(0,f)}return a}function Kt(t,e,i){const s=t.currentDevicePixelRatio,n=0!==i?Math.max(i/2,.5):0;return Math.round((e-n)*s)/s+n}function Gt(t,e){(e=e||t.getContext("2d")).save(),e.resetTransform(),e.clearRect(0,0,t.width,t.height),e.restore()}function Zt(t,e,i,s){let n,o,a,r,l;const h=e.pointStyle,c=e.rotation,d=e.radius;let u=(c||0)*Mt;if(h&&"object"==typeof h&&(n=h.toString(),"[object HTMLImageElement]"===n||"[object HTMLCanvasElement]"===n))return t.save(),t.translate(i,s),t.rotate(u),t.drawImage(h,-h.width/2,-h.height/2,h.width,h.height),void t.restore();if(!(isNaN(d)||d<=0)){switch(t.beginPath(),h){default:t.arc(i,s,d,0,yt),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(u)*d,s-Math.cos(u)*d),u+=Pt,t.lineTo(i+Math.sin(u)*d,s-Math.cos(u)*d),u+=Pt,t.lineTo(i+Math.sin(u)*d,s-Math.cos(u)*d),t.closePath();break;case"rectRounded":l=.516*d,r=d-l,o=Math.cos(u+St)*r,a=Math.sin(u+St)*r,t.arc(i-o,s-a,l,u-_t,u-kt),t.arc(i+a,s-o,l,u-kt,u),t.arc(i+o,s+a,l,u,u+kt),t.arc(i-a,s+o,l,u+kt,u+_t),t.closePath();break;case"rect":if(!c){r=Math.SQRT1_2*d,t.rect(i-r,s-r,2*r,2*r);break}u+=St;case"rectRot":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+a,s-o),t.lineTo(i+o,s+a),t.lineTo(i-a,s+o),t.closePath();break;case"crossRot":u+=St;case"cross":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o);break;case"star":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o),u+=St,o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o);break;case"line":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a);break;case"dash":t.moveTo(i,s),t.lineTo(i+Math.cos(u)*d,s+Math.sin(u)*d)}t.fill(),e.borderWidth>0&&t.stroke()}}function Jt(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.x<e.right+i&&t.y>e.top-i&&t.y<e.bottom+i}function Qt(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()}function te(t){t.restore()}function ee(t,e,i,s,n){if(!e)return t.lineTo(i.x,i.y);if("middle"===n){const s=(e.x+i.x)/2;t.lineTo(s,e.y),t.lineTo(s,i.y)}else"after"===n!=!!s?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y);t.lineTo(i.x,i.y)}function ie(t,e,i,s){if(!e)return t.lineTo(i.x,i.y);t.bezierCurveTo(s?e.cp1x:e.cp2x,s?e.cp1y:e.cp2y,s?i.cp2x:i.cp1x,s?i.cp2y:i.cp1y,i.x,i.y)}function se(t,e,i,s,n,o={}){const a=Y(e)?e:[e],r=o.strokeWidth>0&&""!==o.strokeColor;let l,h;for(t.save(),t.font=n.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);$(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,o),l=0;l<a.length;++l)h=a[l],r&&(o.strokeColor&&(t.strokeStyle=o.strokeColor),$(o.strokeWidth)||(t.lineWidth=o.strokeWidth),t.strokeText(h,i,s,o.maxWidth)),t.fillText(h,i,s,o.maxWidth),ne(t,i,s,h,o),s+=n.lineHeight;t.restore()}function ne(t,e,i,s,n){if(n.strikethrough||n.underline){const o=t.measureText(s),a=e-o.actualBoundingBoxLeft,r=e+o.actualBoundingBoxRight,l=i-o.actualBoundingBoxAscent,h=i+o.actualBoundingBoxDescent,c=n.strikethrough?(l+h)/2:h;t.strokeStyle=t.fillStyle,t.beginPath(),t.lineWidth=n.decorationWidth||2,t.moveTo(a,c),t.lineTo(r,c),t.stroke()}}function oe(t,e){const{x:i,y:s,w:n,h:o,radius:a}=e;t.arc(i+a.topLeft,s+a.topLeft,a.topLeft,-kt,_t,!0),t.lineTo(i,s+o-a.bottomLeft),t.arc(i+a.bottomLeft,s+o-a.bottomLeft,a.bottomLeft,_t,kt,!0),t.lineTo(i+n-a.bottomRight,s+o),t.arc(i+n-a.bottomRight,s+o-a.bottomRight,a.bottomRight,kt,0,!0),t.lineTo(i+n,s+a.topRight),t.arc(i+n-a.topRight,s+a.topRight,a.topRight,0,-kt,!0),t.lineTo(i+a.topLeft,s)}function ae(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const re=(t,e,i)=>ae(t,i,(s=>t[s][e]<i)),le=(t,e,i)=>ae(t,i,(s=>t[s][e]>=i));function he(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const ce=["push","pop","shift","splice","unshift"];function de(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),ce.forEach((e=>{const i="_onData"+ht(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function ue(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(ce.forEach((e=>{delete t[e]})),delete t._chartjs)}function fe(t){const e=new Set;let i,s;for(i=0,s=t.length;i<s;++i)e.add(t[i]);return e.size===s?t:Array.from(e)}function ge(){return"undefined"!=typeof window&&"undefined"!=typeof document}function pe(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function me(t,e,i){let s;return"string"==typeof t?(s=parseInt(t,10),-1!==t.indexOf("%")&&(s=s/100*e.parentNode[i])):s=t,s}const xe=t=>window.getComputedStyle(t,null);function be(t,e){return xe(t).getPropertyValue(e)}const _e=["top","right","bottom","left"];function ye(t,e,i){const s={};i=i?"-"+i:"";for(let n=0;n<4;n++){const o=_e[n];s[o]=parseFloat(t[e+"-"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}function ve(t,e){const{canvas:i,currentDevicePixelRatio:s}=e,n=xe(i),o="border-box"===n.boxSizing,a=ye(n,"padding"),r=ye(n,"border","width"),{x:l,y:h,box:c}=function(t,e){const i=t.native||t,s=i.touches,n=s&&s.length?s[0]:i,{offsetX:o,offsetY:a}=n;let r,l,h=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(o,a,i.target))r=o,l=a;else{const t=e.getBoundingClientRect();r=n.clientX-t.left,l=n.clientY-t.top,h=!0}return{x:r,y:l,box:h}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const we=t=>Math.round(10*t)/10;function Me(t,e,i,s){const n=xe(t),o=ye(n,"margin"),a=me(n.maxWidth,t,"clientWidth")||wt,r=me(n.maxHeight,t,"clientHeight")||wt,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=pe(t);if(o){const t=o.getBoundingClientRect(),a=xe(o),r=ye(a,"border","width"),l=ye(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=me(a.maxWidth,o,"clientWidth"),n=me(a.maxHeight,o,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||wt,maxHeight:n||wt}}(t,e,i);let{width:h,height:c}=l;if("content-box"===n.boxSizing){const t=ye(n,"border","width"),e=ye(n,"padding");h-=e.width+t.width,c-=e.height+t.height}return h=Math.max(0,h-o.width),c=Math.max(0,s?Math.floor(h/s):c-o.height),h=we(Math.min(h,a,l.maxWidth)),c=we(Math.min(c,r,l.maxHeight)),h&&!c&&(c=we(h/2)),{width:h,height:c}}function ke(t,e,i){const s=e||1,n=Math.floor(t.height*s),o=Math.floor(t.width*s);t.height=n/s,t.width=o/s;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const Se=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function Pe(t,e){const i=be(t,e),s=i&&i.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function De(t,e){return"native"in t?{x:t.x,y:t.y}:ve(t,e)}function Ce(t,e,i,s){const{controller:n,data:o,_sorted:a}=t,r=n._cachedMeta.iScale;if(r&&e===r.axis&&"r"!==e&&a&&o.length){const t=r._reversePixels?le:re;if(!s)return t(o,e,i);if(n._sharedOptions){const s=o[0],n="function"==typeof s.getRange&&s.getRange(e);if(n){const s=t(o,e,i-n),a=t(o,e,i+n);return{lo:s.lo,hi:a.hi}}}}return{lo:0,hi:o.length-1}}function Oe(t,e,i,s,n){const o=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=o.length;t<i;++t){const{index:i,data:r}=o[t],{lo:l,hi:h}=Ce(o[t],e,a,n);for(let t=l;t<=h;++t){const e=r[t];e.skip||s(e,i,t)}}}function Ae(t,e,i,s){const n=[];if(!Jt(e,t.chartArea,t._minPadding))return n;return Oe(t,i,e,(function(t,i,o){t.inRange(e.x,e.y,s)&&n.push({element:t,datasetIndex:i,index:o})}),!0),n}function Te(t,e,i,s,n){let o=[];const a=function(t){const e=-1!==t.indexOf("x"),i=-1!==t.indexOf("y");return function(t,s){const n=e?Math.abs(t.x-s.x):0,o=i?Math.abs(t.y-s.y):0;return Math.sqrt(Math.pow(n,2)+Math.pow(o,2))}}(i);let r=Number.POSITIVE_INFINITY;return Oe(t,i,e,(function(i,l,h){const c=i.inRange(e.x,e.y,n);if(s&&!c)return;const d=i.getCenterPoint(n);if(!Jt(d,t.chartArea,t._minPadding)&&!c)return;const u=a(e,d);u<r?(o=[{element:i,datasetIndex:l,index:h}],r=u):u===r&&o.push({element:i,datasetIndex:l,index:h})})),o}function Le(t,e,i,s,n){return Jt(e,t.chartArea,t._minPadding)?"r"!==i||s?Te(t,e,i,s,n):function(t,e,i,s){let n=[];return Oe(t,i,e,(function(t,i,o){const{startAngle:a,endAngle:r}=t.getProps(["startAngle","endAngle"],s),{angle:l}=Bt(t,{x:e.x,y:e.y});Ht(l,a,r)&&n.push({element:t,datasetIndex:i,index:o})})),n}(t,e,i,n):[]}function Re(t,e,i,s){const n=De(e,t),o=[],a=i.axis,r="x"===a?"inXRange":"inYRange";let l=!1;return function(t,e){const i=t.getSortedVisibleDatasetMetas();let s,n,o;for(let t=0,a=i.length;t<a;++t){({index:s,data:n}=i[t]);for(let t=0,i=n.length;t<i;++t)o=n[t],o.skip||e(o,s,t)}}(t,((t,e,i)=>{t[r](n[a],s)&&o.push({element:t,datasetIndex:e,index:i}),t.inRange(n.x,n.y,s)&&(l=!0)})),i.intersect&&!l?[]:o}var Ee={modes:{index(t,e,i,s){const n=De(e,t),o=i.axis||"x",a=i.intersect?Ae(t,n,o,s):Le(t,n,o,!1,s),r=[];return a.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=a[0].index,i=t.data[e];i&&!i.skip&&r.push({element:i,datasetIndex:t.index,index:e})})),r):[]},dataset(t,e,i,s){const n=De(e,t),o=i.axis||"xy";let a=i.intersect?Ae(t,n,o,s):Le(t,n,o,!1,s);if(a.length>0){const e=a[0].datasetIndex,i=t.getDatasetMeta(e).data;a=[];for(let t=0;t<i.length;++t)a.push({element:i[t],datasetIndex:e,index:t})}return a},point:(t,e,i,s)=>Ae(t,De(e,t),i.axis||"xy",s),nearest:(t,e,i,s)=>Le(t,De(e,t),i.axis||"xy",i.intersect,s),x:(t,e,i,s)=>Re(t,e,{axis:"x",intersect:i.intersect},s),y:(t,e,i,s)=>Re(t,e,{axis:"y",intersect:i.intersect},s)}};const Ie=new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/),ze=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function Fe(t,e){const i=(""+t).match(Ie);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}function Be(t,e){const i={},s=U(e),n=s?Object.keys(e):e,o=U(t)?s?i=>K(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of n)i[t]=+o(t)||0;return i}function Ve(t){return Be(t,{top:"y",right:"x",bottom:"y",left:"x"})}function We(t){return Be(t,["topLeft","topRight","bottomLeft","bottomRight"])}function Ne(t){const e=Ve(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function He(t,e){t=t||{},e=e||bt.font;let i=K(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let s=K(t.style,e.style);s&&!(""+s).match(ze)&&(console.warn('Invalid font style specified: "'+s+'"'),s="");const n={family:K(t.family,e.family),lineHeight:Fe(K(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:K(t.weight,e.weight),string:""};return n.string=Ut(n),n}function je(t,e,i,s){let n,o,a,r=!0;for(n=0,o=t.length;n<o;++n)if(a=t[n],void 0!==a&&(void 0!==e&&"function"==typeof a&&(a=a(e),r=!1),void 0!==i&&Y(a)&&(a=a[i%a.length],r=!1),void 0!==a))return s&&!r&&(s.cacheable=!1),a}function $e(t,e,i){const{min:s,max:n}=t,o=Z(e,(n-s)/2),a=(t,e)=>i&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function Ye(t,e){return Object.assign(Object.create(t),e)}const Ue=["left","top","right","bottom"];function Xe(t,e){return t.filter((t=>t.pos===e))}function qe(t,e){return t.filter((t=>-1===Ue.indexOf(t.pos)&&t.box.axis===e))}function Ke(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function Ge(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Ue.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o<a;++o){r=t[o];const{fullSize:a}=r.box,l=i[r.stack],h=l&&r.stackWeight/l.weight;r.horizontal?(r.width=h?h*s:a&&e.availableWidth,r.height=n):(r.width=s,r.height=h?h*n:a&&e.availableHeight)}return i}function Ze(t,e,i,s){return Math.max(t[i],e[i])+Math.max(t[s],e[s])}function Je(t,e){t.top=Math.max(t.top,e.top),t.left=Math.max(t.left,e.left),t.bottom=Math.max(t.bottom,e.bottom),t.right=Math.max(t.right,e.right)}function Qe(t,e,i,s){const{pos:n,box:o}=i,a=t.maxPadding;if(!U(n)){i.size&&(t[n]-=i.size);const e=s[i.stack]||{size:0,count:1};e.size=Math.max(e.size,i.horizontal?o.height:o.width),i.size=e.size/e.count,t[n]+=i.size}o.getPadding&&Je(a,o.getPadding());const r=Math.max(0,e.outerWidth-Ze(a,t,"left","right")),l=Math.max(0,e.outerHeight-Ze(a,t,"top","bottom")),h=r!==t.w,c=l!==t.h;return t.w=r,t.h=l,i.horizontal?{same:h,other:c}:{same:c,other:h}}function ti(t,e){const i=e.maxPadding;function s(t){const s={left:0,top:0,right:0,bottom:0};return t.forEach((t=>{s[t]=Math.max(e[t],i[t])})),s}return s(t?["left","right"]:["top","bottom"])}function ei(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;o<a;++o){r=t[o],l=r.box,l.update(r.width||e.w,r.height||e.h,ti(r.horizontal,e));const{same:a,other:d}=Qe(e,i,r,s);h|=a&&n.length,c=c||d,l.fullSize||n.push(r)}return h&&ei(n,e,i,s)||c}function ii(t,e,i,s,n){t.top=i,t.left=e,t.right=e+s,t.bottom=i+n,t.width=s,t.height=n}function si(t,e,i,s){const n=i.padding;let{x:o,y:a}=e;for(const r of t){const t=r.box,l=s[r.stack]||{count:1,placed:0,weight:1},h=r.stackWeight/l.weight||1;if(r.horizontal){const s=e.w*h,o=l.size||t.height;ct(l.start)&&(a=l.start),t.fullSize?ii(t,n.left,a,i.outerWidth-n.right-n.left,o):ii(t,e.left+l.placed,a,s,o),l.start=a,l.placed+=s,a=t.bottom}else{const s=e.h*h,a=l.size||t.width;ct(l.start)&&(o=l.start),t.fullSize?ii(t,o,n.top,a,i.outerHeight-n.bottom-n.top):ii(t,o,e.top+l.placed,a,s),l.start=o,l.placed+=s,o=t.right}}e.x=o,e.y=a}bt.set("layout",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}});var ni={addBox(t,e){t.boxes||(t.boxes=[]),e.fullSize=e.fullSize||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw(t){e.draw(t)}}]},t.boxes.push(e)},removeBox(t,e){const i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure(t,e,i){e.fullSize=i.fullSize,e.position=i.position,e.weight=i.weight},update(t,e,i,s){if(!t)return;const n=Ne(t.options.layout.padding),o=Math.max(e-n.width,0),a=Math.max(i-n.height,0),r=function(t){const e=function(t){const e=[];let i,s,n,o,a,r;for(i=0,s=(t||[]).length;i<s;++i)n=t[i],({position:o,options:{stack:a,stackWeight:r=1}}=n),e.push({index:i,box:n,pos:o,horizontal:n.isHorizontal(),weight:n.weight,stack:a&&o+a,stackWeight:r});return e}(t),i=Ke(e.filter((t=>t.box.fullSize)),!0),s=Ke(Xe(e,"left"),!0),n=Ke(Xe(e,"right")),o=Ke(Xe(e,"top"),!0),a=Ke(Xe(e,"bottom")),r=qe(e,"x"),l=qe(e,"y");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Xe(e,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;Q(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,d=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),u=Object.assign({},n);Je(u,Ne(s));const f=Object.assign({maxPadding:u,w:o,h:a,x:n.left,y:n.top},n),g=Ge(l.concat(h),d);ei(r.fullSize,f,d,g),ei(l,f,d,g),ei(h,f,d,g)&&ei(l,f,d,g),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(f),si(r.leftAndTop,f,d,g),f.x+=f.w,f.y+=f.h,si(r.rightAndBottom,f,d,g),t.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},Q(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(f.w,f.h,{left:0,top:0,right:0,bottom:0})}))}};function oi(t,e=[""],i=t,s,n=(()=>t[0])){ct(s)||(s=mi("_fallback",t));const o={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:s,_getTarget:n,override:n=>oi([n,...t],e,i,s)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>ci(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=mi(li(o,t),i),ct(n))return hi(t,n)?gi(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>xi(t).includes(e),ownKeys:t=>xi(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function ai(t,e,i,s){const n={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:ri(t,s),setContext:e=>ai(t,e,i,s),override:n=>ai(t.override(n),e,i,s)};return new Proxy(n,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>ci(t,e,(()=>function(t,e,i){const{_proxy:s,_context:n,_subProxy:o,_descriptors:a}=t;let r=s[e];dt(r)&&a.isScriptable(e)&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t),e=e(o,a||s),r.delete(t),hi(t,e)&&(e=gi(n._scopes,n,t,e));return e}(e,r,t,i));Y(r)&&r.length&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_descriptors:r}=i;if(ct(o.index)&&s(t))e=e[o.index%e.length];else if(U(e[0])){const i=e,s=n._scopes.filter((t=>t!==i));e=[];for(const l of i){const i=gi(s,n,t,l);e.push(ai(i,o,a&&a[t],r))}}return e}(e,r,t,a.isIndexable));hi(e,r)&&(r=ai(r,n,o&&o[e],a));return r}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function ri(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:dt(i)?i:()=>i,isIndexable:dt(s)?s:()=>s}}const li=(t,e)=>t?t+ht(e):e,hi=(t,e)=>U(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function ci(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const s=i();return t[e]=s,s}function di(t,e,i){return dt(t)?t(e,i):t}const ui=(t,e)=>!0===t?e:"string"==typeof t?lt(e,t):void 0;function fi(t,e,i,s,n){for(const o of e){const e=ui(i,o);if(e){t.add(e);const o=di(e._fallback,i,n);if(ct(o)&&o!==i&&o!==s)return o}else if(!1===e&&ct(s)&&i!==s)return null}return!1}function gi(t,e,i,s){const n=e._rootScopes,o=di(e._fallback,i,s),a=[...t,...n],r=new Set;r.add(s);let l=pi(r,a,i,o||i,s);return null!==l&&((!ct(o)||o===i||(l=pi(r,a,o,l,s),null!==l))&&oi(Array.from(r),[""],n,o,(()=>function(t,e,i){const s=t._getTarget();e in s||(s[e]={});const n=s[e];if(Y(n)&&U(i))return i;return n}(e,i,s))))}function pi(t,e,i,s,n){for(;i;)i=fi(t,e,i,s,n);return i}function mi(t,e){for(const i of e){if(!i)continue;const e=i[t];if(ct(e))return e}}function xi(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}const bi=Number.EPSILON||1e-14,_i=(t,e)=>e<t.length&&!t[e].skip&&t[e],yi=t=>"x"===t?"y":"x";function vi(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=Vt(o,n),l=Vt(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function wi(t,e="x"){const i=yi(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=_i(t,0);for(a=0;a<s;++a)if(r=l,l=h,h=_i(t,a+1),l){if(h){const t=h[e]-l[e];n[a]=0!==t?(h[i]-l[i])/t:0}o[a]=r?h?Ct(n[a-1])!==Ct(n[a])?0:(n[a-1]+n[a])/2:n[a-1]:n[a]}!function(t,e,i){const s=t.length;let n,o,a,r,l,h=_i(t,0);for(let c=0;c<s-1;++c)l=h,h=_i(t,c+1),l&&h&&(Lt(e[c],0,bi)?i[c]=i[c+1]=0:(n=i[c]/e[c],o=i[c+1]/e[c],r=Math.pow(n,2)+Math.pow(o,2),r<=9||(a=3/Math.sqrt(r),i[c]=n*a*e[c],i[c+1]=o*a*e[c])))}(t,n,o),function(t,e,i="x"){const s=yi(i),n=t.length;let o,a,r,l=_i(t,0);for(let h=0;h<n;++h){if(a=r,r=l,l=_i(t,h+1),!r)continue;const n=r[i],c=r[s];a&&(o=(n-a[i])/3,r[`cp1${i}`]=n-o,r[`cp1${s}`]=c-o*e[h]),l&&(o=(l[i]-n)/3,r[`cp2${i}`]=n+o,r[`cp2${s}`]=c+o*e[h])}}(t,o,e)}function Mi(t,e,i){return Math.max(Math.min(t,i),e)}function ki(t,e,i,s,n){let o,a,r,l;if(e.spanGaps&&(t=t.filter((t=>!t.skip))),"monotone"===e.cubicInterpolationMode)wi(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o<a;++o)r=t[o],l=vi(i,r,t[Math.min(o+1,a-(s?0:1))%a],e.tension),r.cp1x=l.previous.x,r.cp1y=l.previous.y,r.cp2x=l.next.x,r.cp2y=l.next.y,i=r}e.capBezierPoints&&function(t,e){let i,s,n,o,a,r=Jt(t[0],e);for(i=0,s=t.length;i<s;++i)a=o,o=r,r=i<s-1&&Jt(t[i+1],e),o&&(n=t[i],a&&(n.cp1x=Mi(n.cp1x,e.left,e.right),n.cp1y=Mi(n.cp1y,e.top,e.bottom)),r&&(n.cp2x=Mi(n.cp2x,e.left,e.right),n.cp2y=Mi(n.cp2y,e.top,e.bottom)))}(t,i)}const Si=t=>0===t||1===t,Pi=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*yt/i),Di=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*yt/i)+1,Ci={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*kt),easeOutSine:t=>Math.sin(t*kt),easeInOutSine:t=>-.5*(Math.cos(_t*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>Si(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>Si(t)?t:Pi(t,.075,.3),easeOutElastic:t=>Si(t)?t:Di(t,.075,.3),easeInOutElastic(t){const e=.1125;return Si(t)?t:t<.5?.5*Pi(2*t,e,.45):.5+.5*Di(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let 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:t=>1-Ci.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*Ci.easeInBounce(2*t):.5*Ci.easeOutBounce(2*t-1)+.5};function Oi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function Ai(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:"middle"===s?i<.5?t.y:e.y:"after"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function Ti(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=Oi(t,n,i),r=Oi(n,o,i),l=Oi(o,e,i),h=Oi(a,r,i),c=Oi(r,l,i);return Oi(h,c,i)}const Li=new Map;function Ri(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=Li.get(i);return s||(s=new Intl.NumberFormat(t,e),Li.set(i,s)),s}(e,i).format(t)}function Ei(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function Ii(t,e){let i,s;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,s=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=s)}function zi(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function Fi(t){return"angle"===t?{between:Ht,compare:Wt,normalize:Nt}:{between:Yt,compare:(t,e)=>t-e,normalize:t=>t}}function Bi({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Vi(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Fi(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Fi(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;h<c&&a(r(e[d%l][s]),n,o);++h)d--,u--;d%=l,u%=l}return u<d&&(u+=l),{start:d,end:u,loop:f,style:t.style}}(t,e,i),g=[];let p,m,x,b=!1,_=null;const y=()=>b||l(n,x,p)&&0!==r(n,x),v=()=>!b||0===r(o,p)||l(o,x,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==x&&(b=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(Bi({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,x=p));return null!==_&&g.push(Bi({start:_,end:d,loop:u,count:a,style:f})),g}function Wi(t,e){const i=[],s=t.segments;for(let n=0;n<s.length;n++){const o=Vi(s[n],t.points,e);o.length&&i.push(...o)}return i}function Ni(t,e){const i=t.points,s=t.options.spanGaps,n=i.length;if(!n)return[];const o=!!t._loop,{start:a,end:r}=function(t,e,i,s){let n=0,o=e-1;if(i&&!s)for(;n<e&&!t[n].skip;)n++;for(;n<e&&t[n].skip;)n++;for(n%=e,i&&(o+=n);o>n&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Hi(t,[{start:a,end:r,loop:o}],i,e);return Hi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r<a?r+n:r,!!t._fullLoop&&0===a&&r===n-1),i,e)}function Hi(t,e,i,s){return s&&s.setContext&&i?function(t,e,i,s){const n=t._chart.getContext(),o=ji(t.options),{_datasetIndex:a,options:{spanGaps:r}}=t,l=i.length,h=[];let c=o,d=e[0].start,u=d;function f(t,e,s,n){const o=r?-1:1;if(t!==e){for(t+=l;i[t%l].skip;)t-=o;for(;i[e%l].skip;)e+=o;t%l!=e%l&&(h.push({start:t%l,end:e%l,loop:s,style:n}),c=n,d=e%l)}}for(const t of e){d=r?d:t.start;let e,o=i[d%l];for(u=d+1;u<=t.end;u++){const r=i[u%l];e=ji(s.setContext(Ye(n,{type:"segment",p0:o,p1:r,p0DataIndex:(u-1)%l,p1DataIndex:u%l,datasetIndex:a}))),$i(e,c)&&f(d,u-1,t.loop,c),o=r,c=e}d<u-1&&f(d,u-1,t.loop,c)}return h}(t,e,i,s):e}function ji(t){return{backgroundColor:t.backgroundColor,borderCapStyle:t.borderCapStyle,borderDash:t.borderDash,borderDashOffset:t.borderDashOffset,borderJoinStyle:t.borderJoinStyle,borderWidth:t.borderWidth,borderColor:t.borderColor}}function $i(t,e){return e&&JSON.stringify(t)!==JSON.stringify(e)}var Yi=Object.freeze({__proto__:null,easingEffects:Ci,color:W,getHoverColor:N,noop:H,uid:j,isNullOrUndef:$,isArray:Y,isObject:U,isFinite:X,finiteOrDefault:q,valueOrDefault:K,toPercentage:G,toDimension:Z,callback:J,each:Q,_elementsEqual:tt,clone:et,_merger:st,merge:nt,mergeIf:ot,_mergerIf:at,_deprecated:function(t,e,i,s){void 0!==e&&console.warn(t+': "'+i+'" is deprecated. Please use "'+s+'" instead')},resolveObjectKey:lt,_capitalize:ht,defined:ct,isFunction:dt,setsEqual:ut,_isClickEvent:ft,toFontString:Ut,_measureText:Xt,_longestText:qt,_alignPixel:Kt,clearCanvas:Gt,drawPoint:Zt,_isPointInArea:Jt,clipArea:Qt,unclipArea:te,_steppedLineTo:ee,_bezierCurveTo:ie,renderText:se,addRoundedRectPath:oe,_lookup:ae,_lookupByKey:re,_rlookupByKey:le,_filterBetween:he,listenArrayEvents:de,unlistenArrayEvents:ue,_arrayUnique:fe,_createResolver:oi,_attachContext:ai,_descriptors:ri,splineCurve:vi,splineCurveMonotone:wi,_updateBezierControlPoints:ki,_isDomSupported:ge,_getParentNode:pe,getStyle:be,getRelativePosition:ve,getMaximumSize:Me,retinaScale:ke,supportsEventListenerOptions:Se,readUsedSize:Pe,fontString:function(t,e,i){return e+" "+t+"px "+i},requestAnimFrame:t,throttled:e,debounce:i,_toLeftRightCenter:s,_alignStartEnd:n,_textX:o,_pointInLine:Oi,_steppedInterpolation:Ai,_bezierInterpolation:Ti,formatNumber:Ri,toLineHeight:Fe,_readValueToProps:Be,toTRBL:Ve,toTRBLCorners:We,toPadding:Ne,toFont:He,resolve:je,_addGrace:$e,createContext:Ye,PI:_t,TAU:yt,PITAU:vt,INFINITY:wt,RAD_PER_DEG:Mt,HALF_PI:kt,QUARTER_PI:St,TWO_THIRDS_PI:Pt,log10:Dt,sign:Ct,niceNum:Ot,_factorize:At,isNumber:Tt,almostEquals:Lt,almostWhole:Rt,_setMinAndMaxByKey:Et,toRadians:It,toDegrees:zt,_decimalPlaces:Ft,getAngleFromPoint:Bt,distanceBetweenPoints:Vt,_angleDiff:Wt,_normalizeAngle:Nt,_angleBetween:Ht,_limitValue:jt,_int16Range:$t,_isBetween:Yt,getRtlAdapter:Ei,overrideTextDirection:Ii,restoreTextDirection:zi,_boundSegment:Vi,_boundSegments:Wi,_computeSegments:Ni});class Ui{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class Xi extends Ui{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const qi={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},Ki=t=>null===t||""===t;const Gi=!!Se&&{passive:!0};function Zi(t,e,i){t.canvas.removeEventListener(e,i,Gi)}function Ji(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function Qi(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||Ji(i.addedNodes,s),e=e&&!Ji(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function ts(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||Ji(i.removedNodes,s),e=e&&!Ji(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const es=new Map;let is=0;function ss(){const t=window.devicePixelRatio;t!==is&&(is=t,es.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function ns(t,i,s){const n=t.canvas,o=n&&pe(n);if(!o)return;const a=e(((t,e)=>{const i=o.clientWidth;s(t,e),i<o.clientWidth&&s()}),window),r=new ResizeObserver((t=>{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||a(i,s)}));return r.observe(o),function(t,e){es.size||window.addEventListener("resize",ss),es.set(t,e)}(t,a),r}function os(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){es.delete(t),es.size||window.removeEventListener("resize",ss)}(t)}function as(t,i,s){const n=t.canvas,o=e((e=>{null!==t.ctx&&s(function(t,e){const i=qi[t.type]||t.type,{x:s,y:n}=ve(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,Gi)}(n,i,o),o}class rs extends Ui{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute("height"),n=t.getAttribute("width");if(t.$chartjs={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",Ki(n)){const e=Pe(t,"width");void 0!==e&&(t.width=e)}if(Ki(s))if(""===t.style.height)t.height=t.width/(e||2);else{const e=Pe(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const i=e.$chartjs.initial;["height","width"].forEach((t=>{const s=i[t];$(s)?e.removeAttribute(t):e.setAttribute(t,s)}));const s=i.style||{};return Object.keys(s).forEach((t=>{e.style[t]=s[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:Qi,detach:ts,resize:ns}[e]||as;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:os,detach:os,resize:os}[e]||Zi)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return Me(t,e,i,s)}isAttached(t){const e=pe(t);return!(!e||!e.isConnected)}}function ls(t){return!ge()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?Xi:rs}var hs=Object.freeze({__proto__:null,_detectPlatform:ls,BasePlatform:Ui,BasicPlatform:Xi,DomPlatform:rs});const cs="transparent",ds={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=W(t||cs),n=s.valid&&W(e||cs);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class us{constructor(t,e,i,s){const n=e[i];s=je([t.to,s,n,t.from]);const o=je([t.from,n,s]);this._active=!0,this._fn=t.fn||ds[t.type||typeof o],this._easing=Ci[t.easing]||Ci.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=je([t.to,e,s,t.from]),this._from=je([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e<i),!this._active)return this._target[s]=a,void this._notify(!0);e<0?this._target[s]=n:(r=e/i%2,r=o&&r>1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t<i.length;t++)i[t][e]()}}bt.set("animation",{delay:void 0,duration:1e3,easing:"easeOutQuart",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0});const fs=Object.keys(bt.animation);bt.describe("animation",{_fallback:!1,_indexable:!1,_scriptable:t=>"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),bt.set("animations",{colors:{type:"color",properties:["color","borderColor","backgroundColor"]},numbers:{type:"number",properties:["x","y","borderWidth","radius","tension"]}}),bt.describe("animations",{_fallback:"animation"}),bt.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}});class gs{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!U(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const s=t[i];if(!U(s))return;const n={};for(const t of fs)n[t]=s[t];(Y(s.properties)&&s.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,n)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e<s.length;e++){const n=t[s[e]];n&&n.active()&&i.push(n.wait())}return Promise.all(i)}(t.options.$animations,i).then((()=>{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if("$"===l.charAt(0))continue;if("options"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new us(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(a.add(this._chart,i),!0):void 0}}function ps(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function ms(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n<o;++n)i.push(s[n].index);return i}function xs(t,e,i,s={}){const n=t.keys,o="single"===s.mode;let a,r,l,h;if(null!==e){for(a=0,r=n.length;a<r;++a){if(l=+n[a],l===i){if(s.all)continue;break}h=t.values[l],X(h)&&(o||0===e||Ct(e)===Ct(h))&&(e+=h)}return e}}function bs(t,e){const i=t&&t.options.stacked;return i||void 0===i&&void 0!==e.stack}function _s(t,e,i){const s=t[e]||(t[e]={});return s[i]||(s[i]={})}function ys(t,e,i,s){for(const n of e.getMatchingVisibleMetas(s).reverse()){const e=t[n.index];if(i&&e>0||!i&&e<0)return n.index}return null}function vs(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;t<d;++t){const i=e[t],{[l]:o,[h]:d}=i;u=(i._stacks||(i._stacks={}))[h]=_s(n,c,o),u[r]=d,u._top=ys(u,a,!0,s.type),u._bottom=ys(u,a,!1,s.type)}}function ws(t,e){const i=t.scales;return Object.keys(i).filter((t=>i[t].axis===e)).shift()}function Ms(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i]}}}const ks=t=>"reset"===t||"none"===t,Ss=(t,e)=>e?t:Object.assign({},t);class Ps{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=bs(t.vScale,t),this.addElements()}updateIndex(t){this.index!==t&&Ms(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>"x"===t?e:"r"===t?s:i,n=e.xAxisID=K(i.xAxisID,ws(t,"x")),o=e.yAxisID=K(i.yAxisID,ws(t,"y")),a=e.rAxisID=K(i.rAxisID,ws(t,"r")),r=e.indexAxis,l=e.iAxisID=s(r,n,o,a),h=e.vAxisID=s(r,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(l),e.vScale=this.getScaleForId(h)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&ue(this._data,this),t._stacked&&Ms(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(U(e))this._data=function(t){const e=Object.keys(t),i=new Array(e.length);let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s],i[s]={x:o,y:t[o]};return i}(e);else if(i!==e){if(i){ue(i,this);const t=this._cachedMeta;Ms(t),t._parsed=[]}e&&Object.isExtensible(e)&&de(e,this),this._syncList=[],this._data=e}}addElements(){const t=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(t.dataset=new this.datasetElementType)}buildOrUpdateElements(t){const e=this._cachedMeta,i=this.getDataset();let s=!1;this._dataCheck();const n=e._stacked;e._stacked=bs(e.vScale,e),e.stack!==i.stack&&(s=!0,Ms(e),e.stack=i.stack),this._resyncElements(t),(s||n!==e._stacked)&&vs(this,e._parsed)}configure(){const t=this.chart.config,e=t.datasetScopeKeys(this._type),i=t.getOptionScopes(this.getDataset(),e,!0);this.options=t.createResolver(i,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(t,e){const{_cachedMeta:i,_data:s}=this,{iScale:n,_stacked:o}=i,a=n.axis;let r,l,h,c=0===t&&e===s.length||i._sorted,d=t>0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=s,i._sorted=!0,h=s;else{h=Y(s[t])?this.parseArrayData(i,s,t,e):U(s[t])?this.parseObjectData(i,s,t,e):this.parsePrimitiveData(i,s,t,e);const n=()=>null===l[a]||d&&l[a]<d[a];for(r=0;r<e;++r)i._parsed[r+t]=l=h[r],c&&(n()&&(c=!1),d=l);i._sorted=c}o&&vs(this,h)}parsePrimitiveData(t,e,i,s){const{iScale:n,vScale:o}=t,a=n.axis,r=o.axis,l=n.getLabels(),h=n===o,c=new Array(s);let d,u,f;for(d=0,u=s;d<u;++d)f=d+i,c[d]={[a]:h||n.parse(l[f],f),[r]:o.parse(e[f],f)};return c}parseArrayData(t,e,i,s){const{xScale:n,yScale:o}=t,a=new Array(s);let r,l,h,c;for(r=0,l=s;r<l;++r)h=r+i,c=e[h],a[r]={x:n.parse(c[0],h),y:o.parse(c[1],h)};return a}parseObjectData(t,e,i,s){const{xScale:n,yScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l=new Array(s);let h,c,d,u;for(h=0,c=s;h<c;++h)d=h+i,u=e[d],l[h]={x:n.parse(lt(u,a),d),y:o.parse(lt(u,r),d)};return l}getParsed(t){return this._cachedMeta._parsed[t]}getDataElement(t){return this._cachedMeta.data[t]}applyStack(t,e,i){const s=this.chart,n=this._cachedMeta,o=e[t.axis];return xs({keys:ms(s,!0),values:e._stacks[t.axis]},o,n.index,{mode:i})}updateRangeFromParsed(t,e,i,s){const n=i[e.axis];let o=null===n?NaN:n;const a=s&&i._stacks[e.axis];s&&a&&(s.values=a,o=xs(s,n,this._cachedMeta.index)),t.min=Math.min(t.min,o),t.max=Math.max(t.max,o)}getMinMax(t,e){const i=this._cachedMeta,s=i._parsed,n=i._sorted&&t===i.iScale,o=s.length,a=this._getOtherScale(t),r=((t,e,i)=>t&&!e.hidden&&e._stacked&&{keys:ms(i,!0),values:null})(e,i,this.chart),l={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:h,max:c}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(a);let d,u;function f(){u=s[d];const e=u[a.axis];return!X(u[t.axis])||h>e||c<e}for(d=0;d<o&&(f()||(this.updateRangeFromParsed(l,t,u,r),!n));++d);if(n)for(d=o-1;d>=0;--d)if(!f()){this.updateRangeFromParsed(l,t,u,r);break}return l}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s][t.axis],X(o)&&i.push(o);return i}getMaxOverflow(){return!1}getLabelAndValue(t){const e=this._cachedMeta,i=e.iScale,s=e.vScale,n=this.getParsed(t);return{label:i?""+i.getLabelForValue(n[i.axis]):"",value:s?""+s.getLabelForValue(n[s.axis]):""}}_update(t){const e=this._cachedMeta;this.update(t||"default"),e._clip=function(t){let e,i,s,n;return U(t)?(e=t.top,i=t.right,s=t.bottom,n=t.left):e=i=s=n=t,{top:e,right:i,bottom:s,left:n,disabled:!1===t}}(K(this.options.clip,function(t,e,i){if(!1===i)return!1;const s=ps(t,i),n=ps(e,i);return{top:n.end,right:s.end,bottom:n.start,left:s.start}}(e.xScale,e.yScale,this.getMaxOverflow())))}update(t){}draw(){const t=this._ctx,e=this.chart,i=this._cachedMeta,s=i.data||[],n=e.chartArea,o=[],a=this._drawStart||0,r=this._drawCount||s.length-a,l=this.options.drawActiveElementsOnTop;let h;for(i.dataset&&i.dataset.draw(t,n,a,r),h=a;h<a+r;++h){const e=s[h];e.hidden||(e.active&&l?o.push(e):e.draw(t,n))}for(h=0;h<o.length;++h)o[h].draw(t,n)}getStyle(t,e){const i=e?"active":"default";return void 0===t&&this._cachedMeta.dataset?this.resolveDatasetElementOptions(i):this.resolveDataElementOptions(t||0,i)}getContext(t,e,i){const s=this.getDataset();let n;if(t>=0&&t<this._cachedMeta.data.length){const e=this._cachedMeta.data[t];n=e.$context||(e.$context=function(t,e,i){return Ye(t,{active:!1,dataIndex:e,parsed:void 0,raw:void 0,element:i,index:e,mode:"default",type:"data"})}(this.getContext(),t,e)),n.parsed=this.getParsed(t),n.raw=s.data[t],n.index=n.dataIndex=t}else n=this.$context||(this.$context=function(t,e){return Ye(t,{active:!1,dataset:void 0,datasetIndex:e,index:e,mode:"default",type:"dataset"})}(this.chart.getContext(),this.index)),n.dataset=s,n.index=n.datasetIndex=this.index;return n.active=!!e,n.mode=i,n}resolveDatasetElementOptions(t){return this._resolveElementOptions(this.datasetElementType.id,t)}resolveDataElementOptions(t,e){return this._resolveElementOptions(this.dataElementType.id,e,t)}_resolveElementOptions(t,e="default",i){const s="active"===e,n=this._cachedDataOpts,o=t+"-"+e,a=n[o],r=this.enableOptionSharing&&ct(i);if(a)return Ss(a,r);const l=this.chart.config,h=l.datasetElementScopeKeys(this._type,t),c=s?[`${t}Hover`,"hover",t,""]:[t,""],d=l.getOptionScopes(this.getDataset(),h),u=Object.keys(bt.elements[t]),f=l.resolveNamedOptions(d,u,(()=>this.getContext(i,s)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Ss(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new gs(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||ks(t)||this.chart._animationsDisabled}updateElement(t,e,i,s){ks(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!ks(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n<s&&this._removeElements(n,s-n)}_insertElements(t,e,i=!0){const s=this._cachedMeta,n=s.data,o=t+e;let a;const r=t=>{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a<o;++a)n[a]=new this.dataElementType;this._parsing&&r(s._parsed),this.parse(t,e),i&&this.updateElements(n,t,e,"reset")}updateElements(t,e,i,s){}_removeElements(t,e){const i=this._cachedMeta;if(this._parsing){const s=i._parsed.splice(t,e);i._stacked&&Ms(i,s)}i.data.splice(t,e)}_sync(t){if(this._parsing)this._syncList.push(t);else{const[e,i,s]=t;this[e](i,s)}this.chart._dataChanges.push([this.index,...t])}_onDataPush(){const t=arguments.length;this._sync(["_insertElements",this.getDataset().data.length-t,t])}_onDataPop(){this._sync(["_removeElements",this._cachedMeta.data.length-1,1])}_onDataShift(){this._sync(["_removeElements",0,1])}_onDataSplice(t,e){e&&this._sync(["_removeElements",t,e]);const i=arguments.length-2;i&&this._sync(["_insertElements",t,i])}_onDataUnshift(){this._sync(["_insertElements",0,arguments.length])}}Ps.defaults={},Ps.prototype.datasetElementType=null,Ps.prototype.dataElementType=null;class Ds{constructor(){this.x=void 0,this.y=void 0,this.active=!1,this.options=void 0,this.$animations=void 0}tooltipPosition(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}hasValue(){return Tt(this.x)&&Tt(this.y)}getProps(t,e){const i=this.$animations;if(!e||!i)return this;const s={};return t.forEach((t=>{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}Ds.defaults={},Ds.defaultRoutes=void 0;const Cs={values:t=>Y(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n="scientific"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=Dt(Math.abs(o)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),Ri(t,s,l)},logarithmic(t,e,i){if(0===t)return"0";const s=t/Math.pow(10,Math.floor(Dt(t)));return 1===s||2===s||5===s?Cs.numeric.call(this,t,e,i):""}};var Os={formatters:Cs};function As(t,e){const i=t.options.ticks,s=i.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),n=i.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;i<s;i++)t[i].major&&e.push(i);return e}(e):[],o=n.length,a=n[0],r=n[o-1],l=[];if(o>s)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;n<t.length;n++)n===a&&(e.push(t[n]),o++,a=i[o*s])}(e,l,n,o/s),l;const h=function(t,e,i){const s=function(t){const e=t.length;let i,s;if(e<2)return!1;for(s=t[0],i=1;i<e;++i)if(t[i]-t[i-1]!==s)return!1;return s}(t),n=e.length/i;if(!s)return Math.max(n,1);const o=At(s);for(let t=0,e=o.length-1;t<e;t++){const e=o[t];if(e>n)return e}return Math.max(n,1)}(n,e,s);if(o>0){let t,i;const s=o>1?Math.round((r-a)/(o-1)):null;for(Ts(e,l,h,$(s)?0:a-s,a),t=0,i=o-1;t<i;t++)Ts(e,l,h,n[t],n[t+1]);return Ts(e,l,h,r,$(s)?e.length:r+s),l}return Ts(e,l,h),l}function Ts(t,e,i,s,n){const o=K(s,0),a=Math.min(K(n,t.length),t.length);let r,l,h,c=0;for(i=Math.ceil(i),n&&(r=n-s,i=r/Math.floor(r/i)),h=o;h<0;)c++,h=Math.round(o+c*i);for(l=Math.max(o,0);l<a;l++)l===h&&(e.push(t[l]),c++,h=Math.round(o+c*i))}bt.set("scale",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:"ticks",grace:0,grid:{display:!0,lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Os.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),bt.route("scale.ticks","color","","color"),bt.route("scale.grid","color","","borderColor"),bt.route("scale.grid","borderColor","","borderColor"),bt.route("scale.title","color","","color"),bt.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t}),bt.describe("scales",{_fallback:"scale"}),bt.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t});const Ls=(t,e,i)=>"top"===e||"left"===e?t[e]+i:t[e]-i;function Rs(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;o<n;o+=s)i.push(t[Math.floor(o)]);return i}function Es(t,e,i){const s=t.ticks.length,n=Math.min(e,s-1),o=t._startPixel,a=t._endPixel,r=1e-6;let l,h=t.getPixelForTick(n);if(!(i&&(l=1===s?Math.max(h-o,a-h):0===e?(t.getPixelForTick(1)-h)/2:(h-t.getPixelForTick(n-1))/2,h+=n<e?l:-l,h<o-r||h>a+r)))return h}function Is(t){return t.drawTicks?t.tickLength:0}function zs(t,e){if(!t.display)return 0;const i=He(t.font,e),s=Ne(t.padding);return(Y(t.text)?t.text.length:1)*i.lineHeight+s.height}function Fs(t,e,i){let n=s(t);return(i&&"right"!==e||!i&&"right"===e)&&(n=(t=>"left"===t?"right":"right"===t?"left":t)(n)),n}class Bs extends Ds{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=q(t,Number.POSITIVE_INFINITY),e=q(e,Number.NEGATIVE_INFINITY),i=q(i,Number.POSITIVE_INFINITY),s=q(s,Number.NEGATIVE_INFINITY),{min:q(t,i),max:q(e,s),minDefined:X(t),maxDefined:X(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const a=this.getMatchingVisibleMetas();for(let r=0,l=a.length;r<l;++r)e=a[r].controller.getMinMax(this,t),n||(i=Math.min(i,e.min)),o||(s=Math.max(s,e.max));return i=o&&i>s?s:i,s=n&&i>s?i:s,{min:q(i,q(s,i)),max:q(s,q(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){J(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=$e(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a<this.ticks.length;this._convertTicksToLabels(r?Rs(this.ticks,a):this.ticks),this.configure(),this.beforeCalculateLabelRotation(),this.calculateLabelRotation(),this.afterCalculateLabelRotation(),o.display&&(o.autoSkip||"auto"===o.source)&&(this.ticks=As(this,this.ticks),this._labelSizes=null),r&&this._convertTicksToLabels(this.ticks),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate()}configure(){let t,e,i=this.options.reverse;this.isHorizontal()?(t=this.left,e=this.right):(t=this.top,e=this.bottom,i=!i),this._startPixel=t,this._endPixel=e,this._reversePixels=i,this._length=e-t,this._alignToPixels=this.options.alignToPixels}afterUpdate(){J(this.options.afterUpdate,[this])}beforeSetDimensions(){J(this.options.beforeSetDimensions,[this])}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0}afterSetDimensions(){J(this.options.afterSetDimensions,[this])}_callHooks(t){this.chart.notifyPlugins(t,this.getContext()),J(this.options[t],[this])}beforeDataLimits(){this._callHooks("beforeDataLimits")}determineDataLimits(){}afterDataLimits(){this._callHooks("afterDataLimits")}beforeBuildTicks(){this._callHooks("beforeBuildTicks")}buildTicks(){return[]}afterBuildTicks(){this._callHooks("afterBuildTicks")}beforeTickToLabelConversion(){J(this.options.beforeTickToLabelConversion,[this])}generateTickLabels(t){const e=this.options.ticks;let i,s,n;for(i=0,s=t.length;i<s;i++)n=t[i],n.label=J(e.callback,[n.value,i,t],this)}afterTickToLabelConversion(){J(this.options.afterTickToLabelConversion,[this])}beforeCalculateLabelRotation(){J(this.options.beforeCalculateLabelRotation,[this])}calculateLabelRotation(){const t=this.options,e=t.ticks,i=this.ticks.length,s=e.minRotation||0,n=e.maxRotation;let o,a,r,l=s;if(!this._isVisible()||!e.display||s>=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=jt(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Is(t.grid)-e.padding-zs(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=zt(Math.min(Math.asin(jt((h.highest.height+6)/o,-1,1)),Math.asin(jt(a/r,-1,1))-Math.asin(jt(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){J(this.options.afterCalculateLabelRotation,[this])}beforeFit(){J(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=zs(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Is(n)+o):(t.height=this.maxHeight,t.width=Is(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=It(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l="top"!==a&&"x"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):"start"===n?d=e.width:"end"===n?c=t.width:(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;"start"===n?(i=0,s=t.height):"end"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){J(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,i;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,i=t.length;e<i;e++)$(t[e].label)&&(t.splice(e,1),i--,e--);this.afterTickToLabelConversion()}_getLabelSizes(){let t=this._labelSizes;if(!t){const e=this.options.ticks.sampleSize;let i=this.ticks;e<i.length&&(i=Rs(i,e)),this._labelSizes=t=this._computeLabelSizes(i,i.length)}return t}_computeLabelSizes(t,e){const{ctx:i,_longestTextCache:s}=this,n=[],o=[];let a,r,l,h,c,d,u,f,g,p,m,x=0,b=0;for(a=0;a<e;++a){if(h=t[a].label,c=this._resolveTickFontOptions(a),i.font=d=c.string,u=s[d]=s[d]||{data:{},gc:[]},f=c.lineHeight,g=p=0,$(h)||Y(h)){if(Y(h))for(r=0,l=h.length;r<l;++r)m=h[r],$(m)||Y(m)||(g=Xt(i,u.data,u.gc,g,m),p+=f)}else g=Xt(i,u.data,u.gc,g,h),p=f;n.push(g),o.push(p),x=Math.max(g,x),b=Math.max(p,b)}!function(t,e){Q(t,(t=>{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n<s;++n)delete t.data[i[n]];i.splice(0,s)}}))}(s,e);const _=n.indexOf(x),y=o.indexOf(b),v=t=>({width:n[t]||0,height:o[t]||0});return{first:v(0),last:v(e-1),widest:v(_),highest:v(y),widths:n,heights:o}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return $t(this._alignToPixels?Kt(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&t<e.length){const i=e[t];return i.$context||(i.$context=function(t,e,i){return Ye(t,{tick:i,index:e,type:"tick"})}(this.getContext(),t,i))}return this.$context||(this.$context=Ye(this.chart.getContext(),{scale:this,type:"scale"}))}_tickSize(){const t=this.options.ticks,e=It(this.labelRotation),i=Math.abs(Math.cos(e)),s=Math.abs(Math.sin(e)),n=this._getLabelSizes(),o=t.autoSkipPadding||0,a=n?n.widest.width+o:0,r=n?n.highest.height+o:0;return this.isHorizontal()?r*i>a*s?a/i:r/s:r*s<a*i?r/i:a/s}_isVisible(){const t=this.options.display;return"auto"!==t?!!t:this.getMatchingVisibleMetas().length>0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:n,position:o}=s,a=n.offset,r=this.isHorizontal(),l=this.ticks.length+(a?1:0),h=Is(n),c=[],d=n.setContext(this.getContext()),u=d.drawBorder?d.borderWidth:0,f=u/2,g=function(t){return Kt(i,t,u)};let p,m,x,b,_,y,v,w,M,k,S,P;if("top"===o)p=g(this.bottom),y=this.bottom-h,w=p-f,k=g(t.top)+f,P=t.bottom;else if("bottom"===o)p=g(this.top),k=t.top,P=g(t.bottom)-f,y=p+f,w=this.top+h;else if("left"===o)p=g(this.right),_=this.right-h,v=p-f,M=g(t.left)+f,S=t.right;else if("right"===o)p=g(this.left),M=t.left,S=g(t.right)-f,_=p+f,v=this.left+h;else if("x"===e){if("center"===o)p=g((t.top+t.bottom)/2+.5);else if(U(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}k=t.top,P=t.bottom,y=p+f,w=y+h}else if("y"===e){if("center"===o)p=g((t.left+t.right)/2);else if(U(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}_=p-f,v=_-h,M=t.left,S=t.right}const D=K(s.ticks.maxTicksLimit,l),C=Math.max(1,Math.ceil(l/D));for(m=0;m<l;m+=C){const t=n.setContext(this.getContext(m)),e=t.lineWidth,s=t.color,o=n.borderDash||[],l=t.borderDashOffset,h=t.tickWidth,d=t.tickColor,u=t.tickBorderDash||[],f=t.tickBorderDashOffset;x=Es(this,m,a),void 0!==x&&(b=Kt(i,x,e),r?_=v=M=S=b:y=w=k=P=b,c.push({tx1:_,ty1:y,tx2:v,ty2:w,x1:M,y1:k,x2:S,y2:P,width:e,color:s,borderDash:o,borderDashOffset:l,tickWidth:h,tickColor:d,tickBorderDash:u,tickBorderDashOffset:f}))}return this._ticksLength=l,this._borderValue=p,c}_computeLabelItems(t){const e=this.axis,i=this.options,{position:s,ticks:n}=i,o=this.isHorizontal(),a=this.ticks,{align:r,crossAlign:l,padding:h,mirror:c}=n,d=Is(i.grid),u=d+h,f=c?-h:u,g=-It(this.labelRotation),p=[];let m,x,b,_,y,v,w,M,k,S,P,D,C="middle";if("top"===s)v=this.bottom-f,w=this._getXAxisLabelAlignment();else if("bottom"===s)v=this.top+f,w=this._getXAxisLabelAlignment();else if("left"===s){const t=this._getYAxisLabelAlignment(d);w=t.textAlign,y=t.x}else if("right"===s){const t=this._getYAxisLabelAlignment(d);w=t.textAlign,y=t.x}else if("x"===e){if("center"===s)v=(t.top+t.bottom)/2+u;else if(U(s)){const t=Object.keys(s)[0],e=s[t];v=this.chart.scales[t].getPixelForValue(e)+u}w=this._getXAxisLabelAlignment()}else if("y"===e){if("center"===s)y=(t.left+t.right)/2-u;else if(U(s)){const t=Object.keys(s)[0],e=s[t];y=this.chart.scales[t].getPixelForValue(e)}w=this._getYAxisLabelAlignment(d).textAlign}"y"===e&&("start"===r?C="top":"end"===r&&(C="bottom"));const O=this._getLabelSizes();for(m=0,x=a.length;m<x;++m){b=a[m],_=b.label;const t=n.setContext(this.getContext(m));M=this.getPixelForTick(m)+n.labelOffset,k=this._resolveTickFontOptions(m),S=k.lineHeight,P=Y(_)?_.length:1;const e=P/2,i=t.color,r=t.textStrokeColor,h=t.textStrokeWidth;let d;if(o?(y=M,D="top"===s?"near"===l||0!==g?-P*S+S/2:"center"===l?-O.highest.height/2-e*S+S:-O.highest.height+S/2:"near"===l||0!==g?S/2:"center"===l?O.highest.height/2-e*S:O.highest.height-P*S,c&&(D*=-1)):(v=M,D=(1-P)*S/2),t.showLabelBackdrop){const e=Ne(t.backdropPadding),i=O.heights[m],s=O.widths[m];let n=v+D-e.top,o=y-e.left;switch(C){case"middle":n-=i/2;break;case"bottom":n-=i}switch(w){case"center":o-=s/2;break;case"right":o-=s}d={left:o,top:n,width:s+e.width,height:i+e.height,color:t.backdropColor}}p.push({rotation:g,label:_,font:k,color:i,strokeColor:r,strokeWidth:h,textOffset:D,textAlign:w,textBaseline:C,translation:[y,v],backdrop:d})}return p}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-It(this.labelRotation))return"top"===t?"left":"right";let i="center";return"start"===e.align?i="left":"end"===e.align&&(i="right"),i}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:i,mirror:s,padding:n}}=this.options,o=t+n,a=this._getLabelSizes().widest.width;let r,l;return"left"===e?s?(l=this.right+n,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l+=a)):(l=this.right-o,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l=this.left)):"right"===e?s?(l=this.left+n,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l-=a)):(l=this.left+o,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l=this.right)):r="right",{textAlign:r,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;return"left"===e||"right"===e?{top:0,left:this.left,bottom:t.height,right:this.right}:"top"===e||"bottom"===e?{top:this.top,left:0,bottom:this.bottom,right:t.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:s,width:n,height:o}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,s,n,o),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const i=this.ticks.findIndex((e=>e.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n<o;++n){const t=s[n];e.drawOnChartArea&&a({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},t),e.drawTicks&&a({x:t.tx1,y:t.ty1},{x:t.tx2,y:t.ty2},{color:t.tickColor,width:t.tickWidth,borderDash:t.tickBorderDash,borderDashOffset:t.tickBorderDashOffset})}}drawBorder(){const{chart:t,ctx:e,options:{grid:i}}=this,s=i.setContext(this.getContext()),n=i.drawBorder?s.borderWidth:0;if(!n)return;const o=i.setContext(this.getContext(0)).lineWidth,a=this._borderValue;let r,l,h,c;this.isHorizontal()?(r=Kt(t,this.left,n)-n/2,l=Kt(t,this.right,o)+o/2,h=c=a):(h=Kt(t,this.top,n)-n/2,c=Kt(t,this.bottom,o)+o/2,r=l=a),e.save(),e.lineWidth=s.borderWidth,e.strokeStyle=s.borderColor,e.beginPath(),e.moveTo(r,h),e.lineTo(l,c),e.stroke(),e.restore()}drawLabels(t){if(!this.options.ticks.display)return;const e=this.ctx,i=this._computeLabelArea();i&&Qt(e,i);const s=this._labelItems||(this._labelItems=this._computeLabelItems(t));let n,o;for(n=0,o=s.length;n<o;++n){const t=s[n],i=t.font,o=t.label;t.backdrop&&(e.fillStyle=t.backdrop.color,e.fillRect(t.backdrop.left,t.backdrop.top,t.backdrop.width,t.backdrop.height)),se(e,o,0,t.textOffset,i,t)}i&&te(e)}drawTitle(){const{ctx:t,options:{position:e,title:i,reverse:s}}=this;if(!i.display)return;const o=He(i.font),a=Ne(i.padding),r=i.align;let l=o.lineHeight/2;"bottom"===e||"center"===e||U(e)?(l+=a.bottom,Y(i.text)&&(l+=o.lineHeight*(i.text.length-1))):l+=a.top;const{titleX:h,titleY:c,maxWidth:d,rotation:u}=function(t,e,i,s){const{top:o,left:a,bottom:r,right:l,chart:h}=t,{chartArea:c,scales:d}=h;let u,f,g,p=0;const m=r-o,x=l-a;if(t.isHorizontal()){if(f=n(s,a,l),U(i)){const t=Object.keys(i)[0],s=i[t];g=d[t].getPixelForValue(s)+m-e}else g="center"===i?(c.bottom+c.top)/2+m-e:Ls(t,i,e);u=l-a}else{if(U(i)){const t=Object.keys(i)[0],s=i[t];f=d[t].getPixelForValue(s)-x+e}else f="center"===i?(c.left+c.right)/2-x+e:Ls(t,i,e);g=n(s,r,o),p="left"===i?-kt:kt}return{titleX:f,titleY:g,maxWidth:u,rotation:p}}(this,l,e,r);se(t,i.text,0,0,o,{color:i.color,maxWidth:d,rotation:u,textAlign:Fs(r,e,s),textBaseline:"middle",translation:[h,c]})}draw(t){this._isVisible()&&(this.drawBackground(),this.drawGrid(t),this.drawBorder(),this.drawTitle(),this.drawLabels(t))}_layers(){const t=this.options,e=t.ticks&&t.ticks.z||0,i=K(t.grid&&t.grid.z,-1);return this._isVisible()&&this.draw===Bs.prototype.draw?[{z:i,draw:t=>{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:i+1,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+"AxisID",s=[];let n,o;for(n=0,o=e.length;n<o;++n){const o=e[n];o[i]!==this.id||t&&o.type!==t||s.push(o)}return s}_resolveTickFontOptions(t){return He(this.options.ticks.setContext(this.getContext(t)).font)}_maxDigits(){const t=this._resolveTickFontOptions(0).lineHeight;return(this.isHorizontal()?this.width:this.height)/t}}class Vs{constructor(t,e,i){this.type=t,this.scope=e,this.override=i,this.items=Object.create(null)}isForType(t){return Object.prototype.isPrototypeOf.call(this.type.prototype,t.prototype)}register(t){const e=Object.getPrototypeOf(t);let i;(function(t){return"id"in t&&"defaults"in t})(e)&&(i=this.register(e));const s=this.items,n=t.id,o=this.scope+"."+n;if(!n)throw new Error("class does not have id: "+t);return n in s||(s[n]=t,function(t,e,i){const s=nt(Object.create(null),[i?bt.get(i):{},bt.get(e),t.defaults]);bt.set(e,s),t.defaultRoutes&&function(t,e){Object.keys(e).forEach((i=>{const s=i.split("."),n=s.pop(),o=[t].concat(s).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");bt.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&bt.describe(e,t.descriptors)}(t,o,i),this.override&&bt.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in bt[s]&&(delete bt[s][i],this.override&&delete gt[i])}}var Ws=new class{constructor(){this.controllers=new Vs(Ps,"datasets",!0),this.elements=new Vs(Ds,"elements"),this.plugins=new Vs(Object,"plugins"),this.scales=new Vs(Bs,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):Q(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=ht(t);J(i["before"+s],[],i),e[t](i),J(i["after"+s],[],i)}_getRegistryForType(t){for(let e=0;e<this._typedRegistries.length;e++){const i=this._typedRegistries[e];if(i.isForType(t))return i}return this.plugins}_get(t,e,i){const s=e.get(t);if(void 0===s)throw new Error('"'+t+'" is not a registered '+i+".");return s}};class Ns{constructor(){this._init=[]}notify(t,e,i,s){"beforeInit"===e&&(this._init=this._createDescriptors(t,!0),this._notify(this._init,t,"install"));const n=s?this._descriptors(t).filter(s):this._descriptors(t),o=this._notify(n,t,e,i);return"afterDestroy"===e&&(this._notify(n,t,"stop"),this._notify(this._init,t,"uninstall")),o}_notify(t,e,i,s){s=s||{};for(const n of t){const t=n.plugin;if(!1===J(t[i],[e,s,n.options],t)&&s.cancelable)return!1}return!0}invalidate(){$(this._cache)||(this._oldCache=this._cache,this._cache=void 0)}_descriptors(t){if(this._cache)return this._cache;const e=this._cache=this._createDescriptors(t);return this._notifyStateChanges(t),e}_createDescriptors(t,e){const i=t&&t.config,s=K(i.options&&i.options.plugins,{}),n=function(t){const e=[],i=Object.keys(Ws.plugins.items);for(let t=0;t<i.length;t++)e.push(Ws.getPlugin(i[t]));const s=t.plugins||[];for(let t=0;t<s.length;t++){const i=s[t];-1===e.indexOf(i)&&e.push(i)}return e}(i);return!1!==s||e?function(t,e,i,s){const n=[],o=t.getContext();for(let a=0;a<e.length;a++){const r=e[a],l=Hs(i[r.id],s);null!==l&&n.push({plugin:r,options:js(t.config,r,l,o)})}return n}(t,n,s,e):[]}_notifyStateChanges(t){const e=this._oldCache||[],i=this._cache,s=(t,e)=>t.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,"stop"),this._notify(s(i,e),t,"start")}}function Hs(t,e){return e||!1!==t?!0===t?{}:t:null}function js(t,e,i,s){const n=t.pluginScopeKeys(e),o=t.getOptionScopes(i,n);return t.createResolver(o,s,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function $s(t,e){const i=bt.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function Ys(t,e){return"x"===t||"y"===t?t:e.axis||("top"===(i=e.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.charAt(0).toLowerCase();var i}function Us(t){const e=t.options||(t.options={});e.plugins=K(e.plugins,{}),e.scales=function(t,e){const i=gt[t.type]||{scales:{}},s=e.scales||{},n=$s(t.type,e),o=Object.create(null),a=Object.create(null);return Object.keys(s).forEach((t=>{const e=s[t];if(!U(e))return console.error(`Invalid scale configuration for scale: ${t}`);if(e._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);const r=Ys(t,e),l=function(t,e){return t===e?"_index_":"_value_"}(r,n),h=i.scales||{};o[r]=o[r]||t,a[t]=ot(Object.create(null),[{axis:r},e,h[r],h[l]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,r=i.indexAxis||$s(n,e),l=(gt[n]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,r),n=i[e+"AxisID"]||o[e]||e;a[n]=a[n]||Object.create(null),ot(a[n],[{axis:e},s[n],l[t]])}))})),Object.keys(a).forEach((t=>{const e=a[t];ot(e,[bt.scales[e.type],bt.scale])})),a}(t,e)}function Xs(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const qs=new Map,Ks=new Set;function Gs(t,e){let i=qs.get(t);return i||(i=e(),qs.set(t,i),Ks.add(i)),i}const Zs=(t,e,i)=>{const s=lt(e,i);void 0!==s&&t.add(s)};class Js{constructor(t){this._config=function(t){return(t=t||{}).data=Xs(t.data),Us(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Xs(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),Us(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return Gs(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return Gs(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return Gs(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return Gs(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>Zs(r,t,e)))),e.forEach((t=>Zs(r,s,t))),e.forEach((t=>Zs(r,gt[n]||{},t))),e.forEach((t=>Zs(r,bt,t))),e.forEach((t=>Zs(r,pt,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),Ks.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,gt[e]||{},bt.datasets[e]||{},{type:e},bt,pt]}resolveNamedOptions(t,e,i,s=[""]){const n={$shared:!0},{resolver:o,subPrefixes:a}=Qs(this._resolverCache,t,s);let r=o;if(function(t,e){const{isScriptable:i,isIndexable:s}=ri(t);for(const n of e){const e=i(n),o=s(n),a=(o||e)&&t[n];if(e&&(dt(a)||tn(a))||o&&Y(a))return!0}return!1}(o,e)){n.$shared=!1;r=ai(o,i=dt(i)?i():i,this.createResolver(t,i,a))}for(const t of e)n[t]=r[t];return n}createResolver(t,e,i=[""],s){const{resolver:n}=Qs(this._resolverCache,t,i);return U(e)?ai(n,e,void 0,s):n}}function Qs(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:oi(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},s.set(n,o)}return o}const tn=t=>U(t)&&Object.getOwnPropertyNames(t).reduce(((e,i)=>e||dt(t[i])),!1);const en=["top","bottom","left","right","chartArea"];function sn(t,e){return"top"===t||"bottom"===t||-1===en.indexOf(t)&&"x"===e}function nn(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function on(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),J(i&&i.onComplete,[t],e)}function an(t){const e=t.chart,i=e.options.animation;J(i&&i.onProgress,[t],e)}function rn(t){return ge()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const ln={},hn=t=>{const e=rn(t);return Object.values(ln).filter((t=>t.canvas===e)).pop()};function cn(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class dn{constructor(t,e){const s=this.config=new Js(e),n=rn(t),o=hn(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas can be reused.");const r=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||ls(n)),this.platform.updateConfig(s);const l=this.platform.acquireContext(n,r.aspectRatio),h=l&&l.canvas,c=h&&h.height,d=h&&h.width;this.id=j(),this.ctx=l,this.canvas=h,this.width=d,this.height=c,this._options=r,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Ns,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=i((t=>this.update(t)),r.resizeDelay||0),this._dataChanges=[],ln[this.id]=this,l&&h?(a.listen(this,"complete",on),a.listen(this,"progress",an),this._initialize(),this.attached&&this.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:i,height:s,_aspectRatio:n}=this;return $(t)?e&&n?n:s?i/s:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():ke(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return Gt(this.canvas,this.ctx),this}stop(){return a.stop(this),this}resize(t,e){a.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?"resize":"attach";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,ke(this,a,!0)&&(this.notifyPlugins("resize",{size:o}),J(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){Q(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=Ys(t,i),n="r"===s,o="x"===s;return{options:i,dposition:n?"chartArea":o?"bottom":"left",dtype:n?"radialLinear":o?"category":"linear"}})))),Q(n,(e=>{const n=e.options,o=n.id,a=Ys(o,n),r=K(n.type,e.dtype);void 0!==n.position&&sn(n.position,a)===sn(e.dposition)||(n.position=e.dposition),s[o]=!0;let l=null;if(o in i&&i[o].type===r)l=i[o];else{l=new(Ws.getScale(r))({id:o,type:r,ctx:this.ctx,chart:this}),i[l.id]=l}l.init(n,t)})),Q(s,((t,e)=>{t||delete i[e]})),Q(i,(t=>{ni.configure(this,t,t.options),ni.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;t<i;++t)this._destroyDatasetMeta(t);t.splice(e,i-e)}this._sortedMetasets=t.slice(0).sort(nn("order","index"))}_removeUnreferencedMetasets(){const{_metasets:t,data:{datasets:e}}=this;t.length>e.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i<s;i++){const s=e[i];let n=this.getDatasetMeta(i);const o=s.type||this.config.type;if(n.type&&n.type!==o&&(this._destroyDatasetMeta(i),n=this.getDatasetMeta(i)),n.type=o,n.indexAxis=s.indexAxis||$s(o,this.options),n.order=s.order||0,n.index=i,n.label=""+s.label,n.visible=this.isDatasetVisible(i),n.controller)n.controller.updateIndex(i),n.controller.linkScales();else{const e=Ws.getController(o),{datasetElementType:s,dataElementType:a}=bt.datasets[o];Object.assign(e.prototype,{dataElementType:Ws.getElement(a),datasetElementType:s&&Ws.getElement(s)}),n.controller=new e(this,i),t.push(n.controller)}}return this._updateMetasets(),t}_resetElements(){Q(this.data.datasets,((t,e)=>{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let o=0;for(let t=0,e=this.data.datasets.length;t<e;t++){const{controller:e}=this.getDatasetMeta(t),i=!s&&-1===n.indexOf(e);e.buildOrUpdateElements(i),o=Math.max(+e.getMaxOverflow(),o)}o=this._minPadding=i.layout.autoPadding?o:0,this._updateLayout(o),s||Q(n,(t=>{t.reset()})),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(nn("z","_idx"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){Q(this.scales,(t=>{ni.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);ut(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){cn(t,s,"_removeElements"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+","+t.splice(1).join(",")))),s=i(0);for(let t=1;t<e;t++)if(!ut(s,i(t)))return;return Array.from(s).map((t=>t.split(","))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins("beforeLayout",{cancelable:!0}))return;ni.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],Q(this.boxes,(t=>{i&&"chartArea"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(!1!==this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t<e;++t)this.getDatasetMeta(t).controller.configure();for(let e=0,i=this.data.datasets.length;e<i;++e)this._updateDataset(e,dt(t)?t({datasetIndex:e}):t);this.notifyPlugins("afterDatasetsUpdate",{mode:t})}}_updateDataset(t,e){const i=this.getDatasetMeta(t),s={meta:i,index:t,mode:e,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetUpdate",s)&&(i.controller._update(e),s.cancelable=!1,this.notifyPlugins("afterDatasetUpdate",s))}render(){!1!==this.notifyPlugins("beforeRender",{cancelable:!0})&&(a.has(this)?this.attached&&!a.running(this)&&a.start(this):(this.draw(),on({chart:this})))}draw(){let t;if(this._resizeBeforeDraw){const{width:t,height:e}=this._resizeBeforeDraw;this._resize(t,e),this._resizeBeforeDraw=null}if(this.clear(),this.width<=0||this.height<=0)return;if(!1===this.notifyPlugins("beforeDraw",{cancelable:!0}))return;const e=this._layers;for(t=0;t<e.length&&e[t].z<=0;++t)e[t].draw(this.chartArea);for(this._drawDatasets();t<e.length;++t)e[t].draw(this.chartArea);this.notifyPlugins("afterDraw")}_getSortedDatasetMetas(t){const e=this._sortedMetasets,i=[];let s,n;for(s=0,n=e.length;s<n;++s){const n=e[s];t&&!n.visible||i.push(n)}return i}getSortedVisibleDatasetMetas(){return this._getSortedDatasetMetas(!0)}_drawDatasets(){if(!1===this.notifyPlugins("beforeDatasetsDraw",{cancelable:!0}))return;const t=this.getSortedVisibleDatasetMetas();for(let e=t.length-1;e>=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,i=t._clip,s=!i.disabled,n=this.chartArea,o={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetDraw",o)&&(s&&Qt(e,{left:!1===i.left?0:n.left-i.left,right:!1===i.right?this.width:n.right+i.right,top:!1===i.top?0:n.top-i.top,bottom:!1===i.bottom?this.height:n.bottom+i.bottom}),t.controller.draw(),s&&te(e),o.cancelable=!1,this.notifyPlugins("afterDatasetDraw",o))}getElementsAtEventForMode(t,e,i,s){const n=Ee.modes[e];return"function"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=Ye(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?"show":"hide",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);ct(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),a.remove(this),t=0,e=this.data.datasets.length;t<e;++t)this._destroyDatasetMeta(t)}destroy(){this.notifyPlugins("beforeDestroy");const{canvas:t,ctx:e}=this;this._stop(),this.config.clearCache(),t&&(this.unbindEvents(),Gt(t,e),this.platform.releaseContext(e),this.canvas=null,this.ctx=null),this.notifyPlugins("destroy"),delete ln[this.id],this.notifyPlugins("afterDestroy")}toBase64Image(...t){return this.canvas.toDataURL(...t)}bindEvents(){this.bindUserEvents(),this.options.responsive?this.bindResponsiveEvents():this.attached=!0}bindUserEvents(){const t=this._listeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};Q(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s("attach",a),this.attached=!0,this.resize(),i("resize",n),i("detach",o)};o=()=>{this.attached=!1,s("resize",n),this._stop(),this._resize(0,0),i("attach",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){Q(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},Q(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?"set":"remove";let n,o,a,r;for("dataset"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller["_"+s+"DatasetHoverStyle"]()),a=0,r=t.length;a<r;++a){o=t[a];const e=o&&this.getDatasetMeta(o.datasetIndex).controller;e&&e[s+"HoverStyle"](o.element,o.datasetIndex,o.index)}}getActiveElements(){return this._active||[]}setActiveElements(t){const e=this._active||[],i=t.map((({datasetIndex:t,index:e})=>{const i=this.getDatasetMeta(t);if(!i)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:i.data[e],index:e}}));!tt(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:Jt(t,this.chartArea,this._minPadding)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins("beforeEvent",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins("afterEvent",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=ft(t),l=function(t,e,i,s){return i&&"mouseout"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,J(n.onHover,[t,a,this],this),r&&J(n.onClick,[t,a,this],this));const h=!tt(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if("mouseout"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}const un=()=>Q(dn.instances,(t=>t._plugins.invalidate())),fn=!0;function gn(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}Object.defineProperties(dn,{defaults:{enumerable:fn,value:bt},instances:{enumerable:fn,value:ln},overrides:{enumerable:fn,value:gt},registry:{enumerable:fn,value:Ws},version:{enumerable:fn,value:"3.7.1"},getChart:{enumerable:fn,value:hn},register:{enumerable:fn,value:(...t)=>{Ws.add(...t),un()}},unregister:{enumerable:fn,value:(...t)=>{Ws.remove(...t),un()}}});class pn{constructor(t){this.options=t||{}}formats(){return gn()}parse(t,e){return gn()}format(t,e){return gn()}add(t,e,i){return gn()}diff(t,e,i){return gn()}startOf(t,e,i){return gn()}endOf(t,e){return gn()}}pn.override=function(t){Object.assign(pn.prototype,t)};var mn={_date:pn};function xn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;e<n;e++)s=s.concat(i[e].controller.getAllParsedValues(t));t._cache.$bar=fe(s.sort(((t,e)=>t-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(ct(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;s<n;++s)o=e.getPixelForValue(i[s]),l();for(a=void 0,s=0,n=e.ticks.length;s<n;++s)o=e.getPixelForTick(s),l();return r}function bn(t,e,i,s){return Y(t)?function(t,e,i,s){const n=i.parse(t[0],s),o=i.parse(t[1],s),a=Math.min(n,o),r=Math.max(n,o);let l=a,h=r;Math.abs(a)>Math.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,s):e[i.axis]=i.parse(t,s),e}function _n(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;h<c;++h)u=e[h],d={},d[n.axis]=r||n.parse(a[h],h),l.push(bn(u,d,o,h));return l}function yn(t){return t&&void 0!==t.barStart&&void 0!==t.barEnd}function vn(t,e,i,s){let n=e.borderSkipped;const o={};if(!n)return void(t.borderSkipped=o);const{start:a,end:r,reverse:l,top:h,bottom:c}=function(t){let e,i,s,n,o;return t.horizontal?(e=t.base>t.x,i="left",s="right"):(e=t.base<t.y,i="bottom",s="top"),e?(n="end",o="start"):(n="start",o="end"),{start:i,end:s,reverse:e,top:n,bottom:o}}(t);"middle"===n&&i&&(t.enableBorderRadius=!0,(i._top||0)===s?n=h:(i._bottom||0)===s?n=c:(o[wn(c,a,r,l)]=!0,n=h)),o[wn(n,a,r,l)]=!0,t.borderSkipped=o}function wn(t,e,i,s){var n,o,a;return s?(a=i,t=Mn(t=(n=t)===(o=e)?a:n===a?o:n,i,e)):t=Mn(t,e,i),t}function Mn(t,e,i){return"start"===t?e:"end"===t?i:t}function kn(t,{inflateAmount:e},i){t.inflateAmount="auto"===e?1===i?.33:0:e}class Sn extends Ps{parsePrimitiveData(t,e,i,s){return _n(t,e,i,s)}parseArrayData(t,e,i,s){return _n(t,e,i,s)}parseObjectData(t,e,i,s){const{iScale:n,vScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l="x"===n.axis?a:r,h="x"===o.axis?a:r,c=[];let d,u,f,g;for(d=i,u=i+s;d<u;++d)g=e[d],f={},f[n.axis]=n.parse(lt(g,l),d),c.push(bn(lt(g,h),f,o,d));return c}updateRangeFromParsed(t,e,i,s){super.updateRangeFromParsed(t,e,i,s);const n=i._custom;n&&e===this._cachedMeta.vScale&&(t.min=Math.min(t.min,n.min),t.max=Math.max(t.max,n.max))}getMaxOverflow(){return 0}getLabelAndValue(t){const e=this._cachedMeta,{iScale:i,vScale:s}=e,n=this.getParsed(t),o=n._custom,a=yn(o)?"["+o.start+", "+o.end+"]":""+s.getLabelForValue(n[s.axis]);return{label:""+i.getLabelForValue(n[i.axis]),value:a}}initialize(){this.enableOptionSharing=!0,super.initialize();this._cachedMeta.stack=this.getDataset().stack}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,i,s){const n="reset"===s,{index:o,_cachedMeta:{vScale:a}}=this,r=a.getBasePixel(),l=a.isHorizontal(),h=this._getRuler(),c=this.resolveDataElementOptions(e,s),d=this.getSharedOptions(c),u=this.includeOptions(s,d);this.updateSharedOptions(d,s,c);for(let c=e;c<e+i;c++){const e=this.getParsed(c),i=n||$(e[a.axis])?{base:r,head:r}:this._calculateBarValuePixels(c),f=this._calculateBarIndexPixels(c,h),g=(e._stacks||{})[a.axis],p={horizontal:l,base:i.base,enableBorderRadius:!g||yn(e._custom)||o===g._top||o===g._bottom,x:l?i.head:f.center,y:l?f.center:i.head,height:l?f.size:Math.abs(i.size),width:l?Math.abs(i.size):f.size};u&&(p.options=d||this.resolveDataElementOptions(c,t[c].active?"active":s));const m=p.options||t[c].options;vn(p,m,g,o),kn(p,m,h.ratio),this.updateElement(t[c],c,p,s)}}_getStacks(t,e){const i=this._cachedMeta.iScale,s=i.getMatchingVisibleMetas(this._type),n=i.options.stacked,o=s.length,a=[];let r,l;for(r=0;r<o;++r)if(l=s[r],l.controller.options.grouped){if(void 0!==e){const t=l.controller.getParsed(e)[l.controller._cachedMeta.vScale.axis];if($(t)||isNaN(t))continue}if((!1===n||-1===a.indexOf(l.stack)||void 0===n&&void 0===l.stack)&&a.push(l.stack),l.index===t)break}return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n<o;++n)s.push(i.getPixelForValue(this.getParsed(n)[i.axis],n));const a=t.barThickness;return{min:a||xn(e),pixels:s,start:i._startPixel,end:i._endPixel,stackCount:this._getStackCount(),scale:i,grouped:t.grouped,ratio:a?1:t.categoryPercentage*t.barPercentage}}_calculateBarValuePixels(t){const{_cachedMeta:{vScale:e,_stacked:i},options:{base:s,minBarLength:n}}=this,o=s||0,a=this.getParsed(t),r=a._custom,l=yn(r);let h,c,d=a[e.axis],u=0,f=i?this.applyStack(e,a,i):d;f!==d&&(u=f-d,f=d),l&&(d=r.barStart,f=r.barEnd-r.barStart,0!==d&&Ct(d)!==Ct(r.barEnd)&&(u=0),u+=d);const g=$(s)||l?u:s;let p=e.getPixelForValue(g);if(h=this.chart.getDataVisibility(t)?e.getPixelForValue(u+f):p,c=h-p,Math.abs(c)<n&&(c=function(t,e,i){return 0!==t?Ct(t):(e.isHorizontal()?1:-1)*(e.min>=i?1:-1)}(c,e,o)*n,d===o&&(p-=c/2),h=p+c),p===e.getPixelForValue(o)){const t=Ct(c)*e.getLineWidthForValue(o)/2;p+=t,c-=t}return{size:c,base:p,head:h,center:h+c/2}}_calculateBarIndexPixels(t,e){const i=e.scale,s=this.options,n=s.skipNull,o=K(s.maxBarThickness,1/0);let a,r;if(e.grouped){const i=n?this._getStackCount(t):e.stackCount,l="flex"===s.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t<n.length-1?n[t+1]:null;const l=i.categoryPercentage;null===a&&(a=o-(null===r?e.end-e.start:r-o)),null===r&&(r=o+o-a);const h=o-(o-Math.min(a,r))/2*l;return{chunk:Math.abs(r-a)/2*l/s,ratio:i.barPercentage,start:h}}(t,e,s,i):function(t,e,i,s){const n=i.barThickness;let o,a;return $(n)?(o=e.min*i.categoryPercentage,a=i.barPercentage):(o=n*s,a=1),{chunk:o/s,ratio:a,start:e.pixels[t]-o/2}}(t,e,s,i),h=this._getStackIndex(this.index,this._cachedMeta.stack,n?t:void 0);a=l.start+l.chunk*h+l.chunk/2,r=Math.min(o,l.chunk*l.ratio)}else a=i.getPixelForValue(this.getParsed(t)[i.axis],t),r=Math.min(o,e.min*e.ratio);return{base:a-r/2,head:a+r/2,center:a,size:r}}draw(){const t=this._cachedMeta,e=t.vScale,i=t.data,s=i.length;let n=0;for(;n<s;++n)null!==this.getParsed(n)[e.axis]&&i[n].draw(this._ctx)}}Sn.id="bar",Sn.defaults={datasetElementType:!1,dataElementType:"bar",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:"number",properties:["x","y","base","width","height"]}}},Sn.overrides={scales:{_index_:{type:"category",offset:!0,grid:{offset:!0}},_value_:{type:"linear",beginAtZero:!0}}};class Pn extends Ps{initialize(){this.enableOptionSharing=!0,super.initialize()}parsePrimitiveData(t,e,i,s){const n=super.parsePrimitiveData(t,e,i,s);for(let t=0;t<n.length;t++)n[t]._custom=this.resolveDataElementOptions(t+i).radius;return n}parseArrayData(t,e,i,s){const n=super.parseArrayData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=K(s[2],this.resolveDataElementOptions(t+i).radius)}return n}parseObjectData(t,e,i,s){const n=super.parseObjectData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=K(s&&s.r&&+s.r,this.resolveDataElementOptions(t+i).radius)}return n}getMaxOverflow(){const t=this._cachedMeta.data;let e=0;for(let i=t.length-1;i>=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:s}=e,n=this.getParsed(t),o=i.getLabelForValue(n.x),a=s.getLabelForValue(n.y),r=n._custom;return{label:e.label,value:"("+o+", "+a+(r?", "+r:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a}=this._cachedMeta,r=this.resolveDataElementOptions(e,s),l=this.getSharedOptions(r),h=this.includeOptions(s,l),c=o.axis,d=a.axis;for(let r=e;r<e+i;r++){const e=t[r],i=!n&&this.getParsed(r),l={},u=l[c]=n?o.getPixelForDecimal(.5):o.getPixelForValue(i[c]),f=l[d]=n?a.getBasePixel():a.getPixelForValue(i[d]);l.skip=isNaN(u)||isNaN(f),h&&(l.options=this.resolveDataElementOptions(r,e.active?"active":s),n&&(l.options.radius=0)),this.updateElement(e,r,l,s)}this.updateSharedOptions(l,s,r)}resolveDataElementOptions(t,e){const i=this.getParsed(t);let s=super.resolveDataElementOptions(t,e);s.$shared&&(s=Object.assign({},s,{$shared:!1}));const n=s.radius;return"active"!==e&&(s.radius=0),s.radius+=K(i&&i._custom,n),s}}Pn.id="bubble",Pn.defaults={datasetElementType:!1,dataElementType:"point",animations:{numbers:{type:"number",properties:["x","y","borderWidth","radius"]}}},Pn.overrides={scales:{x:{type:"linear"},y:{type:"linear"}},plugins:{tooltip:{callbacks:{title:()=>""}}}};class Dn extends Ps{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let n,o,a=t=>+i[t];if(U(i[t])){const{key:t="value"}=this._parsing;a=e=>+lt(i[e],t)}for(n=t,o=t+e;n<o;++n)s._parsed[n]=a(n)}}_getRotation(){return It(this.options.rotation-90)}_getCircumference(){return It(this.options.circumference)}_getRotationExtents(){let t=yt,e=-yt;for(let i=0;i<this.chart.data.datasets.length;++i)if(this.chart.isDatasetVisible(i)){const s=this.chart.getDatasetMeta(i).controller,n=s._getRotation(),o=s._getCircumference();t=Math.min(t,n),e=Math.max(e,n+o)}return{rotation:t,circumference:e-t}}update(t){const e=this.chart,{chartArea:i}=e,s=this._cachedMeta,n=s.data,o=this.getMaxBorderWidth()+this.getMaxOffset(n)+this.options.spacing,a=Math.max((Math.min(i.width,i.height)-o)/2,0),r=Math.min(G(this.options.cutout,a),1),l=this._getRingWeight(this.index),{circumference:h,rotation:c}=this._getRotationExtents(),{ratioX:d,ratioY:u,offsetX:f,offsetY:g}=function(t,e,i){let s=1,n=1,o=0,a=0;if(e<yt){const r=t,l=r+e,h=Math.cos(r),c=Math.sin(r),d=Math.cos(l),u=Math.sin(l),f=(t,e,s)=>Ht(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>Ht(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(kt,c,u),x=g(_t,h,d),b=g(_t+kt,c,u);s=(p-x)/2,n=(m-b)/2,o=-(p+x)/2,a=-(m+b)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(c,h,r),p=(i.width-o)/d,m=(i.height-o)/u,x=Math.max(Math.min(p,m)/2,0),b=Z(this.options.radius,x),_=(b-Math.max(b*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=f*b,this.offsetY=g*b,s.total=this.calculateTotal(),this.outerRadius=b-_*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-_*l,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/yt)}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,f=this.resolveDataElementOptions(e,s),g=this.getSharedOptions(f),p=this.includeOptions(s,g);let m,x=this._getRotation();for(m=0;m<e;++m)x+=this._circumference(m,n);for(m=e;m<e+i;++m){const e=this._circumference(m,n),i=t[m],o={x:l+this.offsetX,y:h+this.offsetY,startAngle:x,endAngle:x+e,circumference:e,outerRadius:u,innerRadius:d};p&&(o.options=g||this.resolveDataElementOptions(m,i.active?"active":s)),x+=e,this.updateElement(i,m,o,s)}this.updateSharedOptions(g,s,f)}calculateTotal(){const t=this._cachedMeta,e=t.data;let i,s=0;for(i=0;i<e.length;i++){const n=t._parsed[i];null===n||isNaN(n)||!this.chart.getDataVisibility(i)||e[i].hidden||(s+=Math.abs(n))}return s}calculateCircumference(t){const e=this._cachedMeta.total;return e>0&&!isNaN(t)?yt*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=Ri(e._parsed[t],i.options.locale);return{label:s[t]||"",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s<n;++s)if(i.isDatasetVisible(s)){o=i.getDatasetMeta(s),t=o.data,a=o.controller;break}if(!t)return 0;for(s=0,n=t.length;s<n;++s)r=a.resolveDataElementOptions(s),"inner"!==r.borderAlign&&(e=Math.max(e,r.borderWidth||0,r.hoverBorderWidth||0));return e}getMaxOffset(t){let e=0;for(let i=0,s=t.length;i<s;++i){const t=this.resolveDataElementOptions(i);e=Math.max(e,t.offset||0,t.hoverOffset||0)}return e}_getRingWeightOffset(t){let e=0;for(let i=0;i<t;++i)this.chart.isDatasetVisible(i)&&(e+=this._getRingWeight(i));return e}_getRingWeight(t){return Math.max(K(this.chart.data.datasets[t].weight,1),0)}_getVisibleDatasetWeightTotal(){return this._getRingWeightOffset(this.chart.data.datasets.length)||1}}Dn.id="doughnut",Dn.defaults={datasetElementType:!1,dataElementType:"arc",animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:"number",properties:["circumference","endAngle","innerRadius","outerRadius","startAngle","x","y","offset","borderWidth","spacing"]}},cutout:"50%",rotation:0,circumference:360,radius:"100%",spacing:0,indexAxis:"r"},Dn.descriptors={_scriptable:t=>"spacing"!==t,_indexable:t=>"spacing"!==t},Dn.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label(t){let e=t.label;const i=": "+t.formattedValue;return Y(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class Cn extends Ps{initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const e=this._cachedMeta,{dataset:i,data:s=[],_dataset:n}=e,o=this.chart._animationsDisabled;let{start:a,count:r}=function(t,e,i){const s=e.length;let n=0,o=s;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:h,max:c,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(n=jt(Math.min(re(r,a.axis,h).lo,i?s:re(e,l,a.getPixelForValue(h)).lo),0,s-1)),o=u?jt(Math.max(re(r,a.axis,c).hi+1,i?0:re(e,l,a.getPixelForValue(c)).hi+1),n,s)-n:s-n}return{start:n,count:o}}(e,s,o);this._drawStart=a,this._drawCount=r,function(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}(e)&&(a=0,r=s.length),i._chart=this.chart,i._datasetIndex=this.index,i._decimated=!!n._decimated,i.points=s;const l=this.resolveDatasetElementOptions(t);this.options.showLine||(l.borderWidth=0),l.segment=this.options.segment,this.updateElement(i,void 0,{animated:!o,options:l},t),this.updateElements(s,a,r,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a,_stacked:r,_dataset:l}=this._cachedMeta,h=this.resolveDataElementOptions(e,s),c=this.getSharedOptions(h),d=this.includeOptions(s,c),u=o.axis,f=a.axis,{spanGaps:g,segment:p}=this.options,m=Tt(g)?g:Number.POSITIVE_INFINITY,x=this.chart._animationsDisabled||n||"none"===s;let b=e>0&&this.getParsed(e-1);for(let h=e;h<e+i;++h){const e=t[h],i=this.getParsed(h),g=x?e:{},_=$(i[f]),y=g[u]=o.getPixelForValue(i[u],h),v=g[f]=n||_?a.getBasePixel():a.getPixelForValue(r?this.applyStack(a,i,r):i[f],h);g.skip=isNaN(y)||isNaN(v)||_,g.stop=h>0&&i[u]-b[u]>m,p&&(g.parsed=i,g.raw=l.data[h]),d&&(g.options=c||this.resolveDataElementOptions(h,e.active?"active":s)),x||this.updateElement(e,h,g,s),b=i}this.updateSharedOptions(c,s,h)}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}Cn.id="line",Cn.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},Cn.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};class On extends Ps{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=Ri(e._parsed[t].r,i.options.locale);return{label:s[t]||"",value:n}}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=this.getDataset(),r=o.options.animation,l=this._cachedMeta.rScale,h=l.xCenter,c=l.yCenter,d=l.getIndexAngle(0)-.5*_t;let u,f=d;const g=360/this.countVisibleElements();for(u=0;u<e;++u)f+=this._computeAngle(u,s,g);for(u=e;u<e+i;u++){const e=t[u];let i=f,p=f+this._computeAngle(u,s,g),m=o.getDataVisibility(u)?l.getDistanceFromCenterForValue(a.data[u]):0;f=p,n&&(r.animateScale&&(m=0),r.animateRotate&&(i=p=d));const x={x:h,y:c,innerRadius:0,outerRadius:m,startAngle:i,endAngle:p,options:this.resolveDataElementOptions(u,e.active?"active":s)};this.updateElement(e,u,x,s)}}countVisibleElements(){const t=this.getDataset(),e=this._cachedMeta;let i=0;return e.data.forEach(((e,s)=>{!isNaN(t.data[s])&&this.chart.getDataVisibility(s)&&i++})),i}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?It(this.resolveDataElementOptions(t,e).angle||i):0}}On.id="polarArea",On.defaults={dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0},On.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label:t=>t.chart.data.labels[t.dataIndex]+": "+t.formattedValue}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class An extends Dn{}An.id="pie",An.defaults={cutout:0,rotation:0,circumference:360,radius:"100%"};class Tn extends Ps{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,"resize"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this.getDataset(),o=this._cachedMeta.rScale,a="reset"===s;for(let r=e;r<e+i;r++){const e=t[r],i=this.resolveDataElementOptions(r,e.active?"active":s),l=o.getPointPositionForValue(r,n.data[r]),h=a?o.xCenter:l.x,c=a?o.yCenter:l.y,d={x:h,y:c,angle:l.angle,skip:isNaN(h)||isNaN(c),options:i};this.updateElement(e,r,d,s)}}}Tn.id="radar",Tn.defaults={datasetElementType:"line",dataElementType:"point",indexAxis:"r",showLine:!0,elements:{line:{fill:"start"}}},Tn.overrides={aspectRatio:1,scales:{r:{type:"radialLinear"}}};class Ln extends Cn{}Ln.id="scatter",Ln.defaults={showLine:!1,fill:!1},Ln.overrides={interaction:{mode:"point"},plugins:{tooltip:{callbacks:{title:()=>"",label:t=>"("+t.label+", "+t.formattedValue+")"}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var Rn=Object.freeze({__proto__:null,BarController:Sn,BubbleController:Pn,DoughnutController:Dn,LineController:Cn,PolarAreaController:On,PieController:An,RadarController:Tn,ScatterController:Ln});function En(t,e,i){const{startAngle:s,pixelMargin:n,x:o,y:a,outerRadius:r,innerRadius:l}=e;let h=n/r;t.beginPath(),t.arc(o,a,r,s-h,i+h),l>n?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+kt,s-kt),t.closePath(),t.clip()}function In(t,e,i,s){const n=Be(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return jt(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:jt(n.innerStart,0,a),innerEnd:jt(n.innerEnd,0,a)}}function zn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Fn(t,e,i,s,n){const{x:o,y:a,startAngle:r,pixelMargin:l,innerRadius:h}=e,c=Math.max(e.outerRadius+s+i-l,0),d=h>0?h+s+i+l:0;let u=0;const f=n-r;if(s){const t=((h>0?h-s:0)+(c>0?c-s:0))/2;u=(f-(0!==t?f*t/(t+s):f))/2}const g=(f-Math.max(.001,f*c-i/_t)/c)/2,p=r+g+u,m=n-g-u,{outerStart:x,outerEnd:b,innerStart:_,innerEnd:y}=In(e,d,c,m-p),v=c-x,w=c-b,M=p+x/v,k=m-b/w,S=d+_,P=d+y,D=p+_/S,C=m-y/P;if(t.beginPath(),t.arc(o,a,c,M,k),b>0){const e=zn(w,k,o,a);t.arc(e.x,e.y,b,k,m+kt)}const O=zn(P,m,o,a);if(t.lineTo(O.x,O.y),y>0){const e=zn(P,C,o,a);t.arc(e.x,e.y,y,m+kt,C+Math.PI)}if(t.arc(o,a,d,m-y/d,p+_/d,!0),_>0){const e=zn(S,D,o,a);t.arc(e.x,e.y,_,D+Math.PI,p-kt)}const A=zn(v,p,o,a);if(t.lineTo(A.x,A.y),x>0){const e=zn(v,M,o,a);t.arc(e.x,e.y,x,p-kt,M)}t.closePath()}function Bn(t,e,i,s,n){const{options:o}=e,{borderWidth:a,borderJoinStyle:r}=o,l="inner"===o.borderAlign;a&&(l?(t.lineWidth=2*a,t.lineJoin=r||"round"):(t.lineWidth=a,t.lineJoin=r||"bevel"),e.fullCircles&&function(t,e,i){const{x:s,y:n,startAngle:o,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),h=e.innerRadius+a;let c;for(i&&En(t,e,o+yt),t.beginPath(),t.arc(s,n,h,o+yt,o,!0),c=0;c<r;++c)t.stroke();for(t.beginPath(),t.arc(s,n,l,o,o+yt),c=0;c<r;++c)t.stroke()}(t,e,l),l&&En(t,e,n),Fn(t,e,i,s,n),t.stroke())}class Vn extends Ds{constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.getProps(["x","y"],i),{angle:n,distance:o}=Bt(s,{x:t,y:e}),{startAngle:a,endAngle:r,innerRadius:l,outerRadius:h,circumference:c}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],i),d=this.options.spacing/2,u=K(c,r-a)>=yt||Ht(n,a,r),f=Yt(o,l+d,h+d);return u&&f}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/2,n=(e.spacing||0)/2;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=i>yt?Math.floor(i/yt):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();let o=0;if(s){o=s/2;const e=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(e)*o,Math.sin(e)*o),this.circumference>=_t&&(o=s)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;const a=function(t,e,i,s){const{fullCircles:n,startAngle:o,circumference:a}=e;let r=e.endAngle;if(n){Fn(t,e,i,s,o+yt);for(let e=0;e<n;++e)t.fill();isNaN(a)||(r=o+a%yt,a%yt==0&&(r+=yt))}return Fn(t,e,i,s,r),t.fill(),r}(t,this,o,n);Bn(t,this,o,n,a),t.restore()}}function Wn(t,e,i=e){t.lineCap=K(i.borderCapStyle,e.borderCapStyle),t.setLineDash(K(i.borderDash,e.borderDash)),t.lineDashOffset=K(i.borderDashOffset,e.borderDashOffset),t.lineJoin=K(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=K(i.borderWidth,e.borderWidth),t.strokeStyle=K(i.borderColor,e.borderColor)}function Nn(t,e,i){t.lineTo(i.x,i.y)}function Hn(t,e,i={}){const s=t.length,{start:n=0,end:o=s-1}=i,{start:a,end:r}=e,l=Math.max(n,a),h=Math.min(o,r),c=n<a&&o<a||n>r&&o>r;return{count:s,start:l,loop:e.loop,ilen:h<l&&!c?s+h-l:h-l}}function jn(t,e,i,s){const{points:n,options:o}=e,{count:a,start:r,loop:l,ilen:h}=Hn(n,i,s),c=function(t){return t.stepped?ee:t.tension||"monotone"===t.cubicInterpolationMode?ie:Nn}(o);let d,u,f,{move:g=!0,reverse:p}=s||{};for(d=0;d<=h;++d)u=n[(r+(p?h-d:d))%a],u.skip||(g?(t.moveTo(u.x,u.y),g=!1):c(t,f,u,p,o.stepped),f=u);return l&&(u=n[(r+(p?h:0))%a],c(t,f,u,p,o.stepped)),!!l}function $n(t,e,i,s){const n=e.points,{count:o,start:a,ilen:r}=Hn(n,i,s),{move:l=!0,reverse:h}=s||{};let c,d,u,f,g,p,m=0,x=0;const b=t=>(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[b(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[b(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(i<f?f=i:i>g&&(g=i),m=(x*m+e)/++x):(_(),t.lineTo(e,i),u=s,x=0,f=g=i),p=i}_()}function Yn(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?$n:jn}Vn.id="arc",Vn.defaults={borderAlign:"center",borderColor:"#fff",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0},Vn.defaultRoutes={backgroundColor:"backgroundColor"};const Un="function"==typeof Path2D;function Xn(t,e,i,s){Un&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Wn(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=Yn(e);for(const r of n)Wn(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class qn extends Ds{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||"monotone"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;ki(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Ni(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Wi(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?Ai:t.tension||"monotone"===t.cubicInterpolationMode?Ti:Oi}(i);let l,h;for(l=0,h=o.length;l<h;++l){const{start:h,end:c}=o[l],d=n[h],u=n[c];if(d===u){a.push(d);continue}const f=r(d,u,Math.abs((s-d[e])/(u[e]-d[e])),i.stepped);f[e]=t[e],a.push(f)}return 1===a.length?a[0]:a}pathSegment(t,e,i){return Yn(this)(t,this,e,i)}path(t,e,i){const s=this.segments,n=Yn(this);let o=this._loop;e=e||0,i=i||this.points.length-e;for(const a of s)o&=n(t,this,a,{start:e,end:e+i-1});return!!o}draw(t,e,i,s){const n=this.options||{};(this.points||[]).length&&n.borderWidth&&(t.save(),Xn(t,this,i,s),t.restore()),this.animated&&(this._pointsUpdated=!1,this._path=void 0)}}function Kn(t,e,i,s){const n=t.options,{[i]:o}=t.getProps([i],s);return Math.abs(e-o)<n.radius+n.hitRadius}qn.id="line",qn.defaults={borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:"default",fill:!1,spanGaps:!1,stepped:!1,tension:0},qn.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},qn.descriptors={_scriptable:!0,_indexable:t=>"borderDash"!==t&&"fill"!==t};class Gn extends Ds{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.options,{x:n,y:o}=this.getProps(["x","y"],i);return Math.pow(t-n,2)+Math.pow(e-o,2)<Math.pow(s.hitRadius+s.radius,2)}inXRange(t,e){return Kn(this,t,"x",e)}inYRange(t,e){return Kn(this,t,"y",e)}getCenterPoint(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}size(t){let e=(t=t||this.options||{}).radius||0;e=Math.max(e,e&&t.hoverRadius||0);return 2*(e+(e&&t.borderWidth||0))}draw(t,e){const i=this.options;this.skip||i.radius<.1||!Jt(this,e,this.size(i)/2)||(t.strokeStyle=i.borderColor,t.lineWidth=i.borderWidth,t.fillStyle=i.backgroundColor,Zt(t,i,this.x,this.y))}getRange(){const t=this.options||{};return t.radius+t.hitRadius}}function Zn(t,e){const{x:i,y:s,base:n,width:o,height:a}=t.getProps(["x","y","base","width","height"],e);let r,l,h,c,d;return t.horizontal?(d=a/2,r=Math.min(i,n),l=Math.max(i,n),h=s-d,c=s+d):(d=o/2,r=i-d,l=i+d,h=Math.min(s,n),c=Math.max(s,n)),{left:r,top:h,right:l,bottom:c}}function Jn(t,e,i,s){return t?0:jt(e,i,s)}function Qn(t){const e=Zn(t),i=e.right-e.left,s=e.bottom-e.top,n=function(t,e,i){const s=t.options.borderWidth,n=t.borderSkipped,o=Ve(s);return{t:Jn(n.top,o.top,0,i),r:Jn(n.right,o.right,0,e),b:Jn(n.bottom,o.bottom,0,i),l:Jn(n.left,o.left,0,e)}}(t,i/2,s/2),o=function(t,e,i){const{enableBorderRadius:s}=t.getProps(["enableBorderRadius"]),n=t.options.borderRadius,o=We(n),a=Math.min(e,i),r=t.borderSkipped,l=s||U(n);return{topLeft:Jn(!l||r.top||r.left,o.topLeft,0,a),topRight:Jn(!l||r.top||r.right,o.topRight,0,a),bottomLeft:Jn(!l||r.bottom||r.left,o.bottomLeft,0,a),bottomRight:Jn(!l||r.bottom||r.right,o.bottomRight,0,a)}}(t,i/2,s/2);return{outer:{x:e.left,y:e.top,w:i,h:s,radius:o},inner:{x:e.left+n.l,y:e.top+n.t,w:i-n.l-n.r,h:s-n.t-n.b,radius:{topLeft:Math.max(0,o.topLeft-Math.max(n.t,n.l)),topRight:Math.max(0,o.topRight-Math.max(n.t,n.r)),bottomLeft:Math.max(0,o.bottomLeft-Math.max(n.b,n.l)),bottomRight:Math.max(0,o.bottomRight-Math.max(n.b,n.r))}}}}function to(t,e,i,s){const n=null===e,o=null===i,a=t&&!(n&&o)&&Zn(t,s);return a&&(n||Yt(e,a.left,a.right))&&(o||Yt(i,a.top,a.bottom))}function eo(t,e){t.rect(e.x,e.y,e.w,e.h)}function io(t,e,i={}){const s=t.x!==i.x?-e:0,n=t.y!==i.y?-e:0,o=(t.x+t.w!==i.x+i.w?e:0)-s,a=(t.y+t.h!==i.y+i.h?e:0)-n;return{x:t.x+s,y:t.y+n,w:t.w+o,h:t.h+a,radius:t.radius}}Gn.id="point",Gn.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:"circle",radius:3,rotation:0},Gn.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};class so extends Ds{constructor(t){super(),this.options=void 0,this.horizontal=void 0,this.base=void 0,this.width=void 0,this.height=void 0,this.inflateAmount=void 0,t&&Object.assign(this,t)}draw(t){const{inflateAmount:e,options:{borderColor:i,backgroundColor:s}}=this,{inner:n,outer:o}=Qn(this),a=(r=o.radius).topLeft||r.topRight||r.bottomLeft||r.bottomRight?oe:eo;var r;t.save(),o.w===n.w&&o.h===n.h||(t.beginPath(),a(t,io(o,e,n)),t.clip(),a(t,io(n,-e,o)),t.fillStyle=i,t.fill("evenodd")),t.beginPath(),a(t,io(n,e)),t.fillStyle=s,t.fill(),t.restore()}inRange(t,e,i){return to(this,t,e,i)}inXRange(t,e){return to(this,t,null,e)}inYRange(t,e){return to(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,base:s,horizontal:n}=this.getProps(["x","y","base","horizontal"],t);return{x:n?(e+s)/2:e,y:n?i:(i+s)/2}}getRange(t){return"x"===t?this.width/2:this.height/2}}so.id="bar",so.defaults={borderSkipped:"start",borderWidth:0,borderRadius:0,inflateAmount:"auto",pointStyle:void 0},so.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var no=Object.freeze({__proto__:null,ArcElement:Vn,LineElement:qn,PointElement:Gn,BarElement:so});function oo(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{value:e})}}function ao(t){t.data.datasets.forEach((t=>{oo(t)}))}var ro={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,i)=>{if(!i.enabled)return void ao(t);const s=t.width;t.data.datasets.forEach(((e,n)=>{const{_data:o,indexAxis:a}=e,r=t.getDatasetMeta(n),l=o||e.data;if("y"===je([a,t.options.indexAxis]))return;if("line"!==r.type)return;const h=t.scales[r.xAxisID];if("linear"!==h.type&&"time"!==h.type)return;if(t.options.parsing)return;let{start:c,count:d}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=jt(re(e,o.axis,a).lo,0,i-1)),s=h?jt(re(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(r,l);if(d<=(i.threshold||4*s))return void oo(e);let u;switch($(o)&&(e._data=l,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),i.algorithm){case"lttb":u=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;c<o-2;c++){let s,n=0,o=0;const h=Math.floor((c+1)*r)+1+e,m=Math.min(Math.floor((c+2)*r)+1,i)+e,x=m-h;for(s=h;s<m;s++)n+=t[s].x,o+=t[s].y;n/=x,o/=x;const b=Math.floor(c*r)+1+e,_=Math.min(Math.floor((c+1)*r)+1,i)+e,{x:y,y:v}=t[p];for(u=f=-1,s=b;s<_;s++)f=.5*Math.abs((y-n)*(t[s].y-v)-(y-t[s].x)*(o-v)),f>u&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(l,c,d,s,i);break;case"min-max":u=function(t,e,i,s){let n,o,a,r,l,h,c,d,u,f,g=0,p=0;const m=[],x=e+i-1,b=t[e].x,_=t[x].x-b;for(n=e;n<e+i;++n){o=t[n],a=(o.x-b)/_*s,r=o.y;const e=0|a;if(e===l)r<u?(u=r,h=n):r>f&&(f=r,c=n),g=(p*g+o.x)/++p;else{const i=n-1;if(!$(h)&&!$(c)){const e=Math.min(h,c),s=Math.max(h,c);e!==d&&e!==i&&m.push({...t[e],x:g}),s!==d&&s!==i&&m.push({...t[s],x:g})}n>0&&i!==d&&m.push(t[i]),m.push(o),l=e,p=0,u=f=r,h=c=d=n}}return m}(l,c,d,s);break;default:throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`)}e._decimated=u}))},destroy(t){ao(t)}};function lo(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=K(i&&i.target,i);return void 0===s&&(s=!!e.backgroundColor),!1!==s&&null!==s&&(!0===s?"origin":s)}(t);if(U(s))return!isNaN(s.value)&&s;let n=parseFloat(s);return X(n)&&Math.floor(n)===n?("-"!==s[0]&&"+"!==s[0]||(n=e+n),!(n===e||n<0||n>=i)&&n):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}class ho{constructor(t){this.x=t.x,this.y=t.y,this.radius=t.radius}pathSegment(t,e,i){const{x:s,y:n,radius:o}=this;return e=e||{start:0,end:yt},t.arc(s,n,o,e.end,e.start,!0),!i.bounds}interpolate(t){const{x:e,y:i,radius:s}=this,n=t.angle;return{x:e+Math.cos(n)*s,y:i+Math.sin(n)*s,angle:n}}}function co(t){return(t.scale||{}).getPointPositionForValue?function(t){const{scale:e,fill:i}=t,s=e.options,n=e.getLabels().length,o=[],a=s.reverse?e.max:e.min,r=s.reverse?e.min:e.max;let l,h,c;if(c="start"===i?a:"end"===i?r:U(i)?i.value:e.getBaseValue(),s.grid.circular)return h=e.getPointPositionForValue(0,a),new ho({x:h.x,y:h.y,radius:e.getDistanceFromCenterForValue(c)});for(l=0;l<n;++l)o.push(e.getPointPositionForValue(l,c));return o}(t):function(t){const{scale:e={},fill:i}=t;let s,n=null;return"start"===i?n=e.bottom:"end"===i?n=e.top:U(i)?n=e.getPixelForValue(i.value):e.getBasePixel&&(n=e.getBasePixel()),X(n)?(s=e.isHorizontal(),{x:s?n:null,y:s?null:n}):null}(t)}function uo(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function fo(t,e,i){const s=[];for(let n=0;n<i.length;n++){const o=i[n],{first:a,last:r,point:l}=go(o,e,"x");if(!(!l||a&&r))if(a)s.unshift(l);else if(t.push(l),!r)break}t.push(...s)}function go(t,e,i){const s=t.interpolate(e,i);if(!s)return{};const n=s[i],o=t.segments,a=t.points;let r=!1,l=!1;for(let t=0;t<o.length;t++){const e=o[t],s=a[e.start][i],h=a[e.end][i];if(Yt(n,s,h)){r=n===s,l=n===h;break}}return{first:r,last:l,point:s}}function po(t){const{chart:e,fill:i,line:s}=t;if(X(i))return function(t,e){const i=t.getDatasetMeta(e);return i&&t.isDatasetVisible(e)?i.dataset:null}(e,i);if("stack"===i)return function(t){const{scale:e,index:i,line:s}=t,n=[],o=s.segments,a=s.points,r=function(t,e){const i=[],s=t.getMatchingVisibleMetas("line");for(let t=0;t<s.length;t++){const n=s[t];if(n.index===e)break;n.hidden||i.unshift(n.dataset)}return i}(e,i);r.push(mo({x:null,y:e.bottom},s));for(let t=0;t<o.length;t++){const e=o[t];for(let t=e.start;t<=e.end;t++)fo(n,a[t],r)}return new qn({points:n,options:{}})}(t);if("shape"===i)return!0;const n=co(t);return n instanceof ho?n:mo(n,s)}function mo(t,e){let i=[],s=!1;return Y(t)?(s=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=uo(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new qn({points:i,options:{tension:0},_loop:s,_fullLoop:s}):null}function xo(t,e,i){let s=t[e].fill;const n=[e];let o;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!X(s))return s;if(o=t[s],!o)return!1;if(o.visible)return s;n.push(s),s=o.fill}return!1}function bo(t,e,i){const{segments:s,points:n}=e;let o=!0,a=!1;t.beginPath();for(const r of s){const{start:s,end:l}=r,h=n[s],c=n[uo(s,l,n)];o?(t.moveTo(h.x,h.y),o=!1):(t.lineTo(h.x,i),t.lineTo(h.x,h.y)),a=!!e.pathSegment(t,r,{move:a}),a?t.closePath():t.lineTo(c.x,i)}t.lineTo(e.first().x,i),t.closePath(),t.clip()}function _o(t,e,i,s){if(s)return;let n=e[t],o=i[t];return"angle"===t&&(n=Nt(n),o=Nt(o)),{property:t,start:n,end:o}}function yo(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function vo(t,e,i){const{top:s,bottom:n}=e.chart.chartArea,{property:o,start:a,end:r}=i||{};"x"===o&&(t.beginPath(),t.rect(a,s,r-a,n-s),t.clip())}function wo(t,e,i,s){const n=e.interpolate(i,s);n&&t.lineTo(n.x,n.y)}function Mo(t,e){const{line:i,target:s,property:n,color:o,scale:a}=e,r=function(t,e,i){const s=t.segments,n=t.points,o=e.points,a=[];for(const t of s){let{start:s,end:r}=t;r=uo(s,r,n);const l=_o(i,n[s],n[r],t.loop);if(!e.segments){a.push({source:t,target:l,start:n[s],end:n[r]});continue}const h=Wi(e,l);for(const e of h){const s=_o(i,o[e.start],o[e.end],e.loop),r=Vi(t,n,s);for(const t of r)a.push({source:t,target:e,start:{[i]:yo(l,s,"start",Math.max)},end:{[i]:yo(l,s,"end",Math.min)}})}}return a}(i,s,n);for(const{source:e,target:l,start:h,end:c}of r){const{style:{backgroundColor:r=o}={}}=e,d=!0!==s;t.save(),t.fillStyle=r,vo(t,a,d&&_o(n,h,c)),t.beginPath();const u=!!i.pathSegment(t,e);let f;if(d){u?t.closePath():wo(t,s,c,n);const e=!!s.pathSegment(t,l,{move:u,reverse:!0});f=u&&e,f||wo(t,s,h,n)}t.closePath(),t.fill(f?"evenodd":"nonzero"),t.restore()}}function ko(t,e,i){const s=po(e),{line:n,scale:o,axis:a}=e,r=n.options,l=r.fill,h=r.backgroundColor,{above:c=h,below:d=h}=l||{};s&&n.points.length&&(Qt(t,i),function(t,e){const{line:i,target:s,above:n,below:o,area:a,scale:r}=e,l=i._loop?"angle":e.axis;t.save(),"x"===l&&o!==n&&(bo(t,s,a.top),Mo(t,{line:i,target:s,color:n,scale:r,property:l}),t.restore(),t.save(),bo(t,s,a.bottom)),Mo(t,{line:i,target:s,color:o,scale:r,property:l}),t.restore()}(t,{line:n,target:s,above:c,below:d,area:i,scale:o,axis:a}),te(t))}var So={id:"filler",afterDatasetsUpdate(t,e,i){const s=(t.data.datasets||[]).length,n=[];let o,a,r,l;for(a=0;a<s;++a)o=t.getDatasetMeta(a),r=o.dataset,l=null,r&&r.options&&r instanceof qn&&(l={visible:t.isDatasetVisible(a),index:a,fill:lo(r,a,s),chart:t,axis:o.controller.options.indexAxis,scale:o.vScale,line:r}),o.$filler=l,n.push(l);for(a=0;a<s;++a)l=n[a],l&&!1!==l.fill&&(l.fill=xo(n,a,i.propagate))},beforeDraw(t,e,i){const s="beforeDraw"===i.drawTime,n=t.getSortedVisibleDatasetMetas(),o=t.chartArea;for(let e=n.length-1;e>=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&ko(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;i&&ko(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;s&&!1!==s.fill&&"beforeDatasetDraw"===i.drawTime&&ko(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const Po=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class Do extends Ds{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=J(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=He(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=Po(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,n,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign="left",n.textBaseline="middle";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const p=i+e/2+n.measureText(t.text).width;o>0&&u+s+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:s},d=Math.max(d,p),u+=s+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:o}}=this,a=Ei(o,this.left,this.width);if(this.isHorizontal()){let o=0,r=n(i,this.left+s,this.right-this.lineWidths[o]);for(const l of e)o!==l.row&&(o=l.row,r=n(i,this.left+s,this.right-this.lineWidths[o])),l.top+=this.top+t+s,l.left=a.leftForLtr(a.x(r),l.width),r+=l.width+s}else{let o=0,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height);for(const l of e)l.col!==o&&(o=l.col,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height)),l.top=r,l.left+=this.left+s,l.left=a.leftForLtr(a.x(l.left),l.width),r+=l.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Qt(t,this),this._draw(),te(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:a,labels:r}=t,l=bt.color,h=Ei(t.rtl,this.left,this.width),c=He(r.font),{color:d,padding:u}=r,f=c.size,g=f/2;let p;this.drawTitle(),s.textAlign=h.textAlign("left"),s.textBaseline="middle",s.lineWidth=.5,s.font=c.string;const{boxWidth:m,boxHeight:x,itemHeight:b}=Po(r,f),_=this.isHorizontal(),y=this._computeTitleHeight();p=_?{x:n(a,this.left+u,this.right-i[0]),y:this.top+u+y,line:0}:{x:this.left+u,y:n(a,this.top+y+u,this.bottom-e[0].height),line:0},Ii(this.ctx,t.textDirection);const v=b+u;this.legendItems.forEach(((w,M)=>{s.strokeStyle=w.fontColor||d,s.fillStyle=w.fontColor||d;const k=s.measureText(w.text).width,S=h.textAlign(w.textAlign||(w.textAlign=r.textAlign)),P=m+g+k;let D=p.x,C=p.y;h.setWidth(this.width),_?M>0&&D+P+u>this.right&&(C=p.y+=v,p.line++,D=p.x=n(a,this.left+u,this.right-i[p.line])):M>0&&C+v>this.bottom&&(D=p.x=D+e[p.line].width+u,p.line++,C=p.y=n(a,this.top+y+u,this.bottom-e[p.line].height));!function(t,e,i){if(isNaN(m)||m<=0||isNaN(x)||x<0)return;s.save();const n=K(i.lineWidth,1);if(s.fillStyle=K(i.fillStyle,l),s.lineCap=K(i.lineCap,"butt"),s.lineDashOffset=K(i.lineDashOffset,0),s.lineJoin=K(i.lineJoin,"miter"),s.lineWidth=n,s.strokeStyle=K(i.strokeStyle,l),s.setLineDash(K(i.lineDash,[])),r.usePointStyle){const o={radius:m*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},a=h.xPlus(t,m/2);Zt(s,o,a,e+g)}else{const o=e+Math.max((f-x)/2,0),a=h.leftForLtr(t,m),r=We(i.borderRadius);s.beginPath(),Object.values(r).some((t=>0!==t))?oe(s,{x:a,y:o,w:m,h:x,radius:r}):s.rect(a,o,m,x),s.fill(),0!==n&&s.stroke()}s.restore()}(h.x(D),C,w),D=o(S,D+m+g,_?D+P:this.right,t.rtl),function(t,e,i){se(s,i.text,t,e+b/2,c,{strikethrough:i.hidden,textAlign:h.textAlign(i.textAlign)})}(h.x(D),C,w),_?p.x+=P+u:p.y+=v})),zi(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=He(e.font),o=Ne(e.padding);if(!e.display)return;const a=Ei(t.rtl,this.left,this.width),r=this.ctx,l=e.position,h=i.size/2,c=o.top+h;let d,u=this.left,f=this.width;if(this.isHorizontal())f=Math.max(...this.lineWidths),d=this.top+c,u=n(t.align,u,this.right-f);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);d=c+n(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const g=n(l,u,u+f);r.textAlign=a.textAlign(s(l)),r.textBaseline="middle",r.strokeStyle=e.color,r.fillStyle=e.color,r.font=i.string,se(r,e.text,g,d,i)}_computeTitleHeight(){const t=this.options.title,e=He(t.font),i=Ne(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(Yt(t,this.left,this.right)&&Yt(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;i<n.length;++i)if(s=n[i],Yt(t,s.left,s.left+s.width)&&Yt(e,s.top,s.top+s.height))return this.legendItems[i];return null}handleEvent(t){const e=this.options;if(!function(t,e){if("mousemove"===t&&(e.onHover||e.onLeave))return!0;if(e.onClick&&("click"===t||"mouseup"===t))return!0;return!1}(t.type,e))return;const i=this._getLegendItemAt(t.x,t.y);if("mousemove"===t.type){const o=this._hoveredItem,a=(n=i,null!==(s=o)&&null!==n&&s.datasetIndex===n.datasetIndex&&s.index===n.index);o&&!a&&J(e.onLeave,[t,o,this],this),this._hoveredItem=i,i&&!a&&J(e.onHover,[t,i,this],this)}else i&&J(e.onClick,[t,i,this],this);var s,n}}var Co={id:"legend",_element:Do,start(t,e,i){const s=t.legend=new Do({ctx:t.ctx,options:i,chart:t});ni.configure(t,s,i),ni.addBox(t,s)},stop(t){ni.removeBox(t,t.legend),delete t.legend},beforeUpdate(t,e,i){const s=t.legend;ni.configure(t,s,i),s.options=i},afterUpdate(t){const e=t.legend;e.buildLabels(),e.adjustHitBoxes()},afterEvent(t,e){e.replay||t.legend.handleEvent(e.event)},defaults:{display:!0,position:"top",align:"center",fullSize:!0,reverse:!1,weight:1e3,onClick(t,e,i){const s=e.datasetIndex,n=i.chart;n.isDatasetVisible(s)?(n.hide(s),e.hidden=!0):(n.show(s),e.hidden=!1)},onHover:null,onLeave:null,labels:{color:t=>t.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=Ne(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:s||a.pointStyle,rotation:a.rotation,textAlign:n||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class Oo extends Ds{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const s=Y(i.text)?i.text.length:1;this._padding=Ne(i.padding);const n=s*He(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=n:this.width=n}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:o,options:a}=this,r=a.align;let l,h,c,d=0;return this.isHorizontal()?(h=n(r,i,o),c=e+t,l=o-i):("left"===a.position?(h=i+t,c=n(r,s,e),d=-.5*_t):(h=o-t,c=n(r,e,s),d=.5*_t),l=s-e),{titleX:h,titleY:c,maxWidth:l,rotation:d}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=He(e.font),n=i.lineHeight/2+this._padding.top,{titleX:o,titleY:a,maxWidth:r,rotation:l}=this._drawArgs(n);se(t,e.text,0,0,i,{color:e.color,maxWidth:r,rotation:l,textAlign:s(e.align),textBaseline:"middle",translation:[o,a]})}}var Ao={id:"title",_element:Oo,start(t,e,i){!function(t,e){const i=new Oo({ctx:t.ctx,options:e,chart:t});ni.configure(t,i,e),ni.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;ni.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;ni.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const To=new WeakMap;var Lo={id:"subtitle",start(t,e,i){const s=new Oo({ctx:t.ctx,options:i,chart:t});ni.configure(t,s,i),ni.addBox(t,s),To.set(t,s)},stop(t){ni.removeBox(t,To.get(t)),To.delete(t)},beforeUpdate(t,e,i){const s=To.get(t);ni.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Ro={average(t){if(!t.length)return!1;let e,i,s=0,n=0,o=0;for(e=0,i=t.length;e<i;++e){const i=t[e].element;if(i&&i.hasValue()){const t=i.tooltipPosition();s+=t.x,n+=t.y,++o}}return{x:s/o,y:n/o}},nearest(t,e){if(!t.length)return!1;let i,s,n,o=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,s=t.length;i<s;++i){const s=t[i].element;if(s&&s.hasValue()){const t=Vt(e,s.getCenterPoint());t<r&&(r=t,n=s)}}if(n){const t=n.tooltipPosition();o=t.x,a=t.y}return{x:o,y:a}}};function Eo(t,e){return e&&(Y(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function Io(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function zo(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Fo(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=He(e.bodyFont),h=He(e.titleFont),c=He(e.footerFont),d=o.length,u=n.length,f=s.length,g=Ne(e.padding);let p=g.height,m=0,x=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(x+=t.beforeBody.length+t.afterBody.length,d&&(p+=d*h.lineHeight+(d-1)*e.titleSpacing+e.titleMarginBottom),x){p+=f*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(x-f)*l.lineHeight+(x-1)*e.bodySpacing}u&&(p+=e.footerMarginTop+u*c.lineHeight+(u-1)*e.footerSpacing);let b=0;const _=function(t){m=Math.max(m,i.measureText(t).width+b)};return i.save(),i.font=h.string,Q(t.title,_),i.font=l.string,Q(t.beforeBody.concat(t.afterBody),_),b=e.displayColors?a+2+e.boxPadding:0,Q(s,(t=>{Q(t.before,_),Q(t.lines,_),Q(t.after,_)})),b=0,i.font=c.string,Q(t.footer,_),i.restore(),m+=g.width,{width:m,height:p}}function Bo(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h="center";return"center"===s?h=n<=(r+l)/2?"left":"right":n<=o/2?h="left":n>=a-o/2&&(h="right"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return"left"===t&&n+o+a>e.width||"right"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h="center"),h}function Vo(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return i<s/2?"top":i>t.height-s/2?"bottom":"center"}(t,i);return{xAlign:i.xAlign||e.xAlign||Bo(t,e,i,s),yAlign:s}}function Wo(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=We(a);let g=function(t,e){let{x:i,width:s}=t;return"right"===e?i-=s:"center"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return"top"===e?s+=i:s-="bottom"===e?n+i:n/2,s}(e,l,h);return"center"===l?"left"===r?g+=h:"right"===r&&(g-=h):"left"===r?g-=Math.max(c,u)+n:"right"===r&&(g+=Math.max(d,f)+n),{x:jt(g,0,s.width-e.width),y:jt(p,0,s.height-e.height)}}function No(t,e,i){const s=Ne(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-s.right:t.x+s.left}function Ho(t){return Eo([],Io(t))}function jo(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class $o extends Ds{constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart||t._chart,this._chart=this.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,i=this.options.setContext(this.getContext()),s=i.enabled&&e.options.animation&&i.animations,n=new gs(this.chart,s);return s._cacheable&&(this._cachedAnimations=Object.freeze(n)),n}getContext(){return this.$context||(this.$context=(t=this.chart.getContext(),e=this,i=this._tooltipItems,Ye(t,{tooltip:e,tooltipItems:i,type:"tooltip"})));var t,e,i}getTitle(t,e){const{callbacks:i}=e,s=i.beforeTitle.apply(this,[t]),n=i.title.apply(this,[t]),o=i.afterTitle.apply(this,[t]);let a=[];return a=Eo(a,Io(s)),a=Eo(a,Io(n)),a=Eo(a,Io(o)),a}getBeforeBody(t,e){return Ho(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const{callbacks:i}=e,s=[];return Q(t,(t=>{const e={before:[],lines:[],after:[]},n=jo(i,t);Eo(e.before,Io(n.beforeLabel.call(this,t))),Eo(e.lines,n.label.call(this,t)),Eo(e.after,Io(n.afterLabel.call(this,t))),s.push(e)})),s}getAfterBody(t,e){return Ho(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const{callbacks:i}=e,s=i.beforeFooter.apply(this,[t]),n=i.footer.apply(this,[t]),o=i.afterFooter.apply(this,[t]);let a=[];return a=Eo(a,Io(s)),a=Eo(a,Io(n)),a=Eo(a,Io(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;a<r;++a)l.push(zo(this.chart,e[a]));return t.filter&&(l=l.filter(((e,s,n)=>t.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),Q(l,(e=>{const i=jo(t.callbacks,e);s.push(i.labelColor.call(this,e)),n.push(i.labelPointStyle.call(this,e)),o.push(i.labelTextColor.call(this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Ro[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Fo(this,i),a=Object.assign({},t,e),r=Vo(this.chart,i,a),l=Wo(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=We(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,x,b,_,y;return"center"===n?(_=u+g/2,"left"===s?(p=d,m=p-o,b=_+o,y=_-o):(p=d+f,m=p+o,b=_-o,y=_+o),x=p):(m="left"===s?d+Math.max(r,h)+o:"right"===s?d+f-Math.max(l,c)-o:this.caretX,"top"===n?(b=u,_=b-o,p=m-o,x=m+o):(b=u+g,_=b+o,p=m+o,x=m-o),y=b),{x1:p,x2:m,x3:x,y1:b,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=Ei(i.rtl,this.x,this.width);for(t.x=No(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline="middle",o=He(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r<n;++r)e.fillText(s[r],l.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+a,r+1===n&&(t.y+=i.titleMarginBottom-a)}}_drawColorBox(t,e,i,s,n){const o=this.labelColors[i],a=this.labelPointStyles[i],{boxHeight:r,boxWidth:l,boxPadding:h}=n,c=He(n.bodyFont),d=No(this,"left",n),u=s.x(d),f=r<c.lineHeight?(c.lineHeight-r)/2:0,g=e.y+f;if(n.usePointStyle){const e={radius:Math.min(l,r)/2,pointStyle:a.pointStyle,rotation:a.rotation,borderWidth:1},i=s.leftForLtr(u,l)+l/2,h=g+r/2;t.strokeStyle=n.multiKeyBackground,t.fillStyle=n.multiKeyBackground,Zt(t,e,i,h),t.strokeStyle=o.borderColor,t.fillStyle=o.backgroundColor,Zt(t,e,i,h)}else{t.lineWidth=o.borderWidth||1,t.strokeStyle=o.borderColor,t.setLineDash(o.borderDash||[]),t.lineDashOffset=o.borderDashOffset||0;const e=s.leftForLtr(u,l-h),i=s.leftForLtr(s.xPlus(u,1),l-h-2),a=We(o.borderRadius);Object.values(a).some((t=>0!==t))?(t.beginPath(),t.fillStyle=n.multiKeyBackground,oe(t,{x:e,y:g,w:l,h:r,radius:a}),t.fill(),t.stroke(),t.fillStyle=o.backgroundColor,t.beginPath(),oe(t,{x:i,y:g+1,w:l-2,h:r-2,radius:a}),t.fill()):(t.fillStyle=n.multiKeyBackground,t.fillRect(e,g,l,r),t.strokeRect(e,g,l,r),t.fillStyle=o.backgroundColor,t.fillRect(i,g+1,l-2,r-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=He(i.bodyFont);let d=c.lineHeight,u=0;const f=Ei(i.rtl,this.x,this.width),g=function(i){e.fillText(i,f.x(t.x+u),t.y+d/2),t.y+=d+n},p=f.textAlign(o);let m,x,b,_,y,v,w;for(e.textAlign=o,e.textBaseline="middle",e.font=c.string,t.x=No(this,p,i),e.fillStyle=i.bodyColor,Q(this.beforeBody,g),u=a&&"right"!==p?"center"===o?l/2+h:l+2+h:0,_=0,v=s.length;_<v;++_){for(m=s[_],x=this.labelTextColors[_],e.fillStyle=x,Q(m.before,g),b=m.lines,a&&b.length&&(this._drawColorBox(e,t,_,f,i),d=Math.max(c.lineHeight,r)),y=0,w=b.length;y<w;++y)g(b[y]),d=c.lineHeight;Q(m.after,g)}u=0,d=c.lineHeight,Q(this.afterBody,g),t.y-=n}drawFooter(t,e,i){const s=this.footer,n=s.length;let o,a;if(n){const r=Ei(i.rtl,this.x,this.width);for(t.x=No(this,i.footerAlign,i),t.y+=i.footerMarginTop,e.textAlign=r.textAlign(i.footerAlign),e.textBaseline="middle",o=He(i.footerFont),e.fillStyle=i.footerColor,e.font=o.string,a=0;a<n;++a)e.fillText(s[a],r.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+i.footerSpacing}}drawBackground(t,e,i,s){const{xAlign:n,yAlign:o}=this,{x:a,y:r}=t,{width:l,height:h}=i,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=We(s.cornerRadius);e.fillStyle=s.backgroundColor,e.strokeStyle=s.borderColor,e.lineWidth=s.borderWidth,e.beginPath(),e.moveTo(a+c,r),"top"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+l-d,r),e.quadraticCurveTo(a+l,r,a+l,r+d),"center"===o&&"right"===n&&this.drawCaret(t,e,i,s),e.lineTo(a+l,r+h-f),e.quadraticCurveTo(a+l,r+h,a+l-f,r+h),"bottom"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+u,r+h),e.quadraticCurveTo(a,r+h,a,r+h-u),"center"===o&&"left"===n&&this.drawCaret(t,e,i,s),e.lineTo(a,r+c),e.quadraticCurveTo(a,r,a+c,r),e.closePath(),e.fill(),s.borderWidth>0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Ro[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Fo(this,t),a=Object.assign({},i,this._size),r=Vo(e,t,a),l=Wo(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=Ne(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),Ii(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),zi(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!tt(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!tt(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if("mouseout"===t.type)return[];if(!s)return e;const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Ro[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}$o.positioners=Ro;var Yo={id:"tooltip",_element:$o,positioners:Ro,afterInit(t,e,i){i&&(t.tooltip=new $o({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip,i={tooltip:e};!1!==t.notifyPlugins("beforeTooltipDraw",i)&&(e&&e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i))},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:H,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(s>0&&e.dataIndex<s)return i[e.dataIndex]}return""},afterTitle:H,beforeBody:H,beforeLabel:H,label(t){if(this&&this.options&&"dataset"===this.options.mode)return t.label+": "+t.formattedValue||t.formattedValue;let e=t.dataset.label||"";e&&(e+=": ");const i=t.formattedValue;return $(i)||(e+=i),e},labelColor(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{borderColor:e.borderColor,backgroundColor:e.backgroundColor,borderWidth:e.borderWidth,borderDash:e.borderDash,borderDashOffset:e.borderDashOffset,borderRadius:0}},labelTextColor(){return this.options.bodyColor},labelPointStyle(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{pointStyle:e.pointStyle,rotation:e.rotation}},afterLabel:H,afterBody:H,beforeFooter:H,footer:H,afterFooter:H}},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:t=>"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},Uo=Object.freeze({__proto__:null,Decimation:ro,Filler:So,Legend:Co,SubTitle:Lo,Title:Ao,Tooltip:Yo});function Xo(t,e,i,s){const n=t.indexOf(e);if(-1===n)return((t,e,i,s)=>("string"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}class qo extends Bs{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if($(t))return null;const i=this.getLabels();return((t,e)=>null===t?null:jt(Math.round(t),0,e))(e=isFinite(e)&&i[e]===t?e:Xo(i,t,K(e,t),this._addedLabels),i.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);"ticks"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){const e=this.getLabels();return t>=0&&t<e.length?e[t]:t}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return"number"!=typeof t&&(t=this.parse(t)),null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function Ko(t,e,{horizontal:i,minRotation:s}){const n=It(s),o=(i?Math.sin(n):Math.cos(n))||.001,a=.75*e*(""+t).length;return Math.min(e/o,a)}qo.id="category",qo.defaults={ticks:{callback:qo.prototype.getLabelForValue}};class Go extends Bs{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return $(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:i}=this.getUserBounds();let{min:s,max:n}=this;const o=t=>s=e?s:t,a=t=>n=i?n:t;if(t){const t=Ct(s),e=Ct(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=1;(n>=Number.MAX_SAFE_INTEGER||s<=Number.MIN_SAFE_INTEGER)&&(e=Math.abs(.05*n)),a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let i=this.getTickLimit();i=Math.max(2,i);const s=function(t,e){const i=[],{bounds:s,step:n,min:o,max:a,precision:r,count:l,maxTicks:h,maxDigits:c,includeBounds:d}=t,u=n||1,f=h-1,{min:g,max:p}=e,m=!$(o),x=!$(a),b=!$(l),_=(p-g)/(c+1);let y,v,w,M,k=Ot((p-g)/f/u)*u;if(k<1e-14&&!m&&!x)return[{value:g},{value:p}];M=Math.ceil(p/k)-Math.floor(g/k),M>f&&(k=Ot(M*k/f/u)*u),$(r)||(y=Math.pow(10,r),k=Math.ceil(k*y)/y),"ticks"===s?(v=Math.floor(g/k)*k,w=Math.ceil(p/k)*k):(v=g,w=p),m&&x&&n&&Rt((a-o)/n,k/1e3)?(M=Math.round(Math.min((a-o)/k,h)),k=(a-o)/M,v=o,w=a):b?(v=m?o:v,w=x?a:w,M=l-1,k=(w-v)/M):(M=(w-v)/k,M=Lt(M,Math.round(M),k/1e3)?Math.round(M):Math.ceil(M));const S=Math.max(Ft(k),Ft(v));y=Math.pow(10,$(r)?S:r),v=Math.round(v*y)/y,w=Math.round(w*y)/y;let P=0;for(m&&(d&&v!==o?(i.push({value:o}),v<o&&P++,Lt(Math.round((v+P*k)*y)/y,o,Ko(o,_,t))&&P++):v<o&&P++);P<M;++P)i.push({value:Math.round((v+P*k)*y)/y});return x&&d&&w!==a?i.length&&Lt(i[i.length-1].value,a,Ko(a,_,t))?i[i.length-1].value=a:i.push({value:a}):x&&w!==a||i.push({value:w}),i}({maxTicks:i,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:!1!==e.includeBounds},this._range||this);return"ticks"===t.bounds&&Et(s,this,"value"),t.reverse?(s.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),s}configure(){const t=this.ticks;let e=this.min,i=this.max;if(super.configure(),this.options.offset&&t.length){const s=(i-e)/Math.max(t.length-1,1)/2;e-=s,i+=s}this._startValue=e,this._endValue=i,this._valueRange=i-e}getLabelForValue(t){return Ri(t,this.chart.options.locale,this.options.ticks.format)}}class Zo extends Go{determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=X(t)?t:0,this.max=X(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,i=It(this.options.ticks.minRotation),s=(t?Math.sin(i):Math.cos(i))||.001,n=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,n.lineHeight/s))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}function Jo(t){return 1===t/Math.pow(10,Math.floor(Dt(t)))}Zo.id="linear",Zo.defaults={ticks:{callback:Os.formatters.numeric}};class Qo extends Bs{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=Go.prototype.parse.apply(this,[t,e]);if(0!==i)return X(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=X(t)?Math.max(0,t):null,this.max=X(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t,a=(t,e)=>Math.pow(10,Math.floor(Dt(t))+e);i===s&&(i<=0?(n(1),o(10)):(n(a(i,-1)),o(a(s,1)))),i<=0&&n(a(s,-1)),s<=0&&o(a(i,1)),this._zero&&this.min!==this._suggestedMin&&i===a(this.min,0)&&n(a(i,-1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=function(t,e){const i=Math.floor(Dt(e.max)),s=Math.ceil(e.max/Math.pow(10,i)),n=[];let o=q(t.min,Math.pow(10,Math.floor(Dt(e.min)))),a=Math.floor(Dt(o)),r=Math.floor(o/Math.pow(10,a)),l=a<0?Math.pow(10,Math.abs(a)):1;do{n.push({value:o,major:Jo(o)}),++r,10===r&&(r=1,++a,l=a>=0?1:l),o=Math.round(r*Math.pow(10,a)*l)/l}while(a<i||a===i&&r<s);const h=q(t.max,o);return n.push({value:h,major:Jo(o)}),n}({min:this._userMin,max:this._userMax},this);return"ticks"===t.bounds&&Et(e,this,"value"),t.reverse?(e.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),e}getLabelForValue(t){return void 0===t?"0":Ri(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=Dt(t),this._valueRange=Dt(this.max)-Dt(t)}getPixelForValue(t){return void 0!==t&&0!==t||(t=this.min),null===t||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(Dt(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function ta(t){const e=t.ticks;if(e.display&&t.display){const t=Ne(e.backdropPadding);return K(e.font&&e.font.size,bt.font.size)+t.height}return 0}function ea(t,e,i,s,n){return t===s||t===n?{start:e-i/2,end:e+i/2}:t<s||t>n?{start:e-i,end:e}:{start:e,end:e+i}}function ia(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),s=[],n=[],o=t._pointLabels.length,a=t.options.pointLabels,r=a.centerPointLabels?_t/o:0;for(let d=0;d<o;d++){const o=a.setContext(t.getPointLabelContext(d));n[d]=o.padding;const u=t.getPointPosition(d,t.drawingArea+n[d],r),f=He(o.font),g=(l=t.ctx,h=f,c=Y(c=t._pointLabels[d])?c:[c],{w:qt(l,h.string,c),h:c.length*h.lineHeight});s[d]=g;const p=Nt(t.getIndexAngle(d)+r),m=Math.round(zt(p));sa(i,e,p,ea(m,u.x,g.w,0,180),ea(m,u.y,g.h,90,270))}var l,h,c;t.setCenterPoint(e.l-i.l,i.r-e.r,e.t-i.t,i.b-e.b),t._pointLabelItems=function(t,e,i){const s=[],n=t._pointLabels.length,o=t.options,a=ta(o)/2,r=t.drawingArea,l=o.pointLabels.centerPointLabels?_t/n:0;for(let o=0;o<n;o++){const n=t.getPointPosition(o,r+a+i[o],l),h=Math.round(zt(Nt(n.angle+kt))),c=e[o],d=aa(n.y,c.h,h),u=na(h),f=oa(n.x,c.w,u);s.push({x:n.x,y:d,textAlign:u,left:f,top:d,right:f+c.w,bottom:d+c.h})}return s}(t,s,n)}function sa(t,e,i,s,n){const o=Math.abs(Math.sin(i)),a=Math.abs(Math.cos(i));let r=0,l=0;s.start<e.l?(r=(e.l-s.start)/o,t.l=Math.min(t.l,e.l-r)):s.end>e.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.start<e.t?(l=(e.t-n.start)/a,t.t=Math.min(t.t,e.t-l)):n.end>e.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function na(t){return 0===t||180===t?"center":t<180?"left":"right"}function oa(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function aa(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function ra(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,yt);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;o<s;o++)i=t.getPointPosition(o,e),n.lineTo(i.x,i.y)}}Qo.id="logarithmic",Qo.defaults={ticks:{callback:Os.formatters.logarithmic,major:{enabled:!0}}};class la extends Go{constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){const t=this._padding=Ne(ta(this.options)/2),e=this.width=this.maxWidth-t.width,i=this.height=this.maxHeight-t.height;this.xCenter=Math.floor(this.left+e/2+t.left),this.yCenter=Math.floor(this.top+i/2+t.top),this.drawingArea=Math.floor(Math.min(e,i)/2)}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!1);this.min=X(t)&&!isNaN(t)?t:0,this.max=X(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/ta(this.options))}generateTickLabels(t){Go.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map(((t,e)=>{const i=J(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:""})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?ia(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return Nt(t*(yt/(this._pointLabels.length||1))+It(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if($(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if($(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t<e.length){const i=e[t];return function(t,e,i){return Ye(t,{label:i,index:e,type:"pointLabel"})}(this.getContext(),t,i)}}getPointPosition(t,e,i=0){const s=this.getIndexAngle(t)-kt+i;return{x:Math.cos(s)*e+this.xCenter,y:Math.sin(s)*e+this.yCenter,angle:s}}getPointPositionForValue(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}getBasePosition(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}getPointLabelPosition(t){const{left:e,top:i,right:s,bottom:n}=this._pointLabelItems[t];return{left:e,top:i,right:s,bottom:n}}drawBackground(){const{backgroundColor:t,grid:{circular:e}}=this.options;if(t){const i=this.ctx;i.save(),i.beginPath(),ra(this,this.getDistanceFromCenterForValue(this._endValue),e,this._pointLabels.length),i.closePath(),i.fillStyle=t,i.fill(),i.restore()}}drawGrid(){const t=this.ctx,e=this.options,{angleLines:i,grid:s}=e,n=this._pointLabels.length;let o,a,r;if(e.pointLabels.display&&function(t,e){const{ctx:i,options:{pointLabels:s}}=t;for(let n=e-1;n>=0;n--){const e=s.setContext(t.getPointLabelContext(n)),o=He(e.font),{x:a,y:r,textAlign:l,left:h,top:c,right:d,bottom:u}=t._pointLabelItems[n],{backdropColor:f}=e;if(!$(f)){const t=Ne(e.backdropPadding);i.fillStyle=f,i.fillRect(h-t.left,c-t.top,d-h+t.width,u-c+t.height)}se(i,t._pointLabels[n],a,r+o.lineHeight/2,o,{color:e.color,textAlign:l,textBaseline:"middle"})}}(this,n),s.display&&this.ticks.forEach(((t,e)=>{if(0!==e){a=this.getDistanceFromCenterForValue(t.value);!function(t,e,i,s){const n=t.ctx,o=e.circular,{color:a,lineWidth:r}=e;!o&&!s||!a||!r||i<0||(n.save(),n.strokeStyle=a,n.lineWidth=r,n.setLineDash(e.borderDash),n.lineDashOffset=e.borderDashOffset,n.beginPath(),ra(t,i,o,s),n.closePath(),n.stroke(),n.restore())}(this,s.setContext(this.getContext(e-1)),a,n)}})),i.display){for(t.save(),o=n-1;o>=0;o--){const s=i.setContext(this.getPointLabelContext(o)),{color:n,lineWidth:l}=s;l&&n&&(t.lineWidth=l,t.strokeStyle=n,t.setLineDash(s.borderDash),t.lineDashOffset=s.borderDashOffset,a=this.getDistanceFromCenterForValue(e.ticks.reverse?this.min:this.max),r=this.getPointPosition(o,a),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(r.x,r.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach(((s,a)=>{if(0===a&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=He(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=Ne(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}se(t,s.label,0,-n,l,{color:r.color})})),t.restore()}drawTitle(){}}la.id="radialLinear",la.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Os.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5,centerPointLabels:!1}},la.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},la.descriptors={angleLines:{_fallback:"grid"}};const ha={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}},ca=Object.keys(ha);function da(t,e){return t-e}function ua(t,e){if($(e))return null;const i=t._adapter,{parser:s,round:n,isoWeekday:o}=t._parseOpts;let a=e;return"function"==typeof s&&(a=s(a)),X(a)||(a="string"==typeof s?i.parse(a,s):i.parse(a)),null===a?null:(n&&(a="week"!==n||!Tt(o)&&!0!==o?i.startOf(a,n):i.startOf(a,"isoWeek",o)),+a)}function fa(t,e,i,s){const n=ca.length;for(let o=ca.indexOf(t);o<n-1;++o){const t=ha[ca[o]],n=t.steps?t.steps:Number.MAX_SAFE_INTEGER;if(t.common&&Math.ceil((i-e)/(n*t.size))<=s)return ca[o]}return ca[n-1]}function ga(t,e,i){if(i){if(i.length){const{lo:s,hi:n}=ae(i,e);t[i[s]>=e?i[s]:i[n]]=!0}}else t[e]=!0}function pa(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a<o;++a)r=e[a],n[r]=a,s.push({value:r,major:!1});return 0!==o&&i?function(t,e,i,s){const n=t._adapter,o=+n.startOf(e[0].value,s),a=e[e.length-1].value;let r,l;for(r=o;r<=a;r=+n.add(r,1,s))l=i[r],l>=0&&(e[l].major=!0);return e}(t,s,n,i):s}class ma extends Bs{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),s=this._adapter=new mn._date(t.adapters.date);ot(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:ua(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||"day";let{min:s,max:n,minDefined:o,maxDefined:a}=this.getUserBounds();function r(t){o||isNaN(t.min)||(s=Math.min(s,t.min)),a||isNaN(t.max)||(n=Math.max(n,t.max))}o&&a||(r(this._getLabelBounds()),"ticks"===t.bounds&&"labels"===t.ticks.source||r(this.getMinMax(!1))),s=X(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=X(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s="labels"===i.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=he(s,n,this.max);return this._unit=e.unit||(i.autoSkip?fa(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=ca.length-1;o>=ca.indexOf(i);o--){const i=ca[o];if(ha[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return ca[i?ca.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&"year"!==this._unit?function(t){for(let e=ca.indexOf(t)+1,i=ca.length;e<i;++e)if(ha[ca[e]].common)return ca[e]}(this._unit):void 0,this.initOffsets(s),t.reverse&&o.reverse(),pa(this,o,this._majorUnit)}initOffsets(t){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=jt(s,0,o),n=jt(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||fa(n.minUnit,e,i,this._getLabelCapacity(e)),a=K(n.stepSize,1),r="week"===o&&n.isoWeekday,l=Tt(r)||!0===r,h={};let c,d,u=e;if(l&&(u=+t.startOf(u,"isoWeek",r)),u=+t.startOf(u,l?"day":o),t.diff(i,e,o)>1e5*a)throw new Error(e+" and "+i+" are too far apart with stepSize of "+a+" "+o);const f="data"===s.ticks.source&&this.getDataTimestamps();for(c=u,d=0;c<i;c=+t.add(c,a,o),d++)ga(h,c,f);return c!==i&&"ticks"!==s.bounds&&1!==d||ga(h,c,f),Object.keys(h).sort(((t,e)=>t-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.time.displayFormats,a=this._unit,r=this._majorUnit,l=a&&o[a],h=r&&o[r],c=i[e],d=r&&h&&c&&c.major,u=this._adapter.format(t,s||(d?h:l)),f=n.ticks.callback;return f?J(f,[u,e,i],this):u}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e<i;++e)s=t[e],s.label=this._tickFormatFunction(s.value,e,t)}getDecimalForValue(t){return null===t?NaN:(t-this.min)/(this.max-this.min)}getPixelForValue(t){const e=this._offsets,i=this.getDecimalForValue(t);return this.getPixelForDecimal((e.start+i)*e.factor)}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return this.min+i*(this.max-this.min)}_getLabelSize(t){const e=this.options.ticks,i=this.ctx.measureText(t).width,s=It(this.isHorizontal()?e.maxRotation:e.minRotation),n=Math.cos(s),o=Math.sin(s),a=this._resolveTickFontOptions(0).size;return{w:i*n+a*o,h:i*o+a*n}}_getLabelCapacity(t){const e=this.options.time,i=e.displayFormats,s=i[e.unit]||i.millisecond,n=this._tickFormatFunction(t,0,pa(this,[t],this._majorUnit),s),o=this._getLabelSize(n),a=Math.floor(this.isHorizontal()?this.width/o.w:this.height/o.h)-1;return a>0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t<e;++t)i=i.concat(s[t].controller.getAllParsedValues(this));return this._cache.data=this.normalize(i)}getLabelTimestamps(){const t=this._cache.labels||[];let e,i;if(t.length)return t;const s=this.getLabels();for(e=0,i=s.length;e<i;++e)t.push(ua(this,s[e]));return this._cache.labels=this._normalized?t:this.normalize(t)}normalize(t){return fe(t.sort(da))}}function xa(t,e,i){let s,n,o,a,r=0,l=t.length-1;i?(e>=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=re(t,"pos",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=re(t,"time",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}ma.id="time",ma.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};class ba extends ma{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=xa(e,this.min),this._tableRange=xa(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o<a;++o)l=t[o],l>=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;o<a;++o)h=s[o+1],r=s[o-1],l=s[o],Math.round((h+r)/2)!==l&&n.push({time:l,pos:o/(a-1)});return n}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),i=this.getLabelTimestamps();return t=e.length&&i.length?this.normalize(e.concat(i)):e.length?e:i,t=this._cache.all=t,t}getDecimalForValue(t){return(xa(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return xa(this._table,i*this._tableRange+this._minPos,!0)}}ba.id="timeseries",ba.defaults=ma.defaults;var _a=Object.freeze({__proto__:null,CategoryScale:qo,LinearScale:Zo,LogarithmicScale:Qo,RadialLinearScale:la,TimeScale:ma,TimeSeriesScale:ba});return dn.register(Rn,_a,no,Uo),dn.helpers={...Yi},dn._adapters=mn,dn.Animation=us,dn.Animations=gs,dn.animator=a,dn.controllers=Ws.controllers.items,dn.DatasetController=Ps,dn.Element=Ds,dn.elements=no,dn.Interaction=Ee,dn.layouts=ni,dn.platforms=hs,dn.Scale=Bs,dn.Ticks=Os,Object.assign(dn,Rn,_a,no,Uo,hs),dn.Chart=dn,"undefined"!=typeof window&&(window.Chart=dn),dn}));
|
@@ -1,365 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! defined( 'myCRED_VERSION' ) ) exit;
|
3 |
-
|
4 |
-
|
5 |
-
if ( ! class_exists( 'myCRED_Addons_Upgrader' ) ) :
|
6 |
-
Class myCRED_Addons_Upgrader {
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Construct
|
10 |
-
*/
|
11 |
-
public function __construct() {
|
12 |
-
|
13 |
-
add_action( 'admin_menu', array( $this, 'mycred_upgrader_menu' ) );
|
14 |
-
add_action( 'admin_notices', array( $this, 'mycred_update_notice') );
|
15 |
-
add_action( 'admin_init', array( $this, 'admin_init') );
|
16 |
-
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_transient' ), 99 );
|
17 |
-
add_filter( 'update_bulk_plugins_complete_actions', array( $this, 'update_actions' ), 99, 2 );
|
18 |
-
|
19 |
-
}
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Register upgrader menu
|
23 |
-
*/
|
24 |
-
public function mycred_upgrader_menu() {
|
25 |
-
|
26 |
-
add_submenu_page(
|
27 |
-
'options.php',
|
28 |
-
'Update',
|
29 |
-
'Update',
|
30 |
-
'manage_options',
|
31 |
-
'mycred-update',
|
32 |
-
array( $this, 'mycred_addons_update' )
|
33 |
-
);
|
34 |
-
|
35 |
-
}
|
36 |
-
|
37 |
-
public function mycred_update_notice() {
|
38 |
-
|
39 |
-
$all_installed_plugins = get_plugins();
|
40 |
-
$mycred_installed_addons = $this->get_installed_mycred_addons( $all_installed_plugins );
|
41 |
-
|
42 |
-
if ( ! empty( $mycred_installed_addons ) ) {
|
43 |
-
|
44 |
-
$is_upgrade_done = get_option( 'mycred_addons_upgrade' );
|
45 |
-
|
46 |
-
if ( false === $is_upgrade_done ) :?>
|
47 |
-
<div class="notice notice-warning is-dismissible">
|
48 |
-
<h2 style="margin-bottom: 8px;">myCred Addons Update Required</h2>
|
49 |
-
<p style="margin-bottom: 8px;">From myCred version 2.3.1 and onwards, you will be able to use our latest license management system that allows you to run your add-ons more smoothly. Please update your add-ons immediately for a better experience!<br /><a href="https://mycred.me/blog/why-do-you-need-to-update-your-mycred-addons/" target="_blank">Why am I seeing this notice?</a></p>
|
50 |
-
<a href="<?php echo admin_url('options.php?page=mycred-update'); ?>" class="button button-primary button-large">Update Addons Now</a>
|
51 |
-
<a class="button button-large" href="<?php echo add_query_arg( 'mycred_addons_upgrader', 'mycred-addons-updated', home_url( $_SERVER['REQUEST_URI'] ) ) ?>">I have already updated</a>
|
52 |
-
<br>
|
53 |
-
<br>
|
54 |
-
</div>
|
55 |
-
<?php endif;
|
56 |
-
|
57 |
-
}
|
58 |
-
|
59 |
-
}
|
60 |
-
|
61 |
-
public function admin_init() {
|
62 |
-
|
63 |
-
global $pagenow;
|
64 |
-
if ( $pagenow == 'options.php' && isset( $_GET['page'] ) && $_GET['page'] == 'mycred-update' ) {
|
65 |
-
remove_all_actions( 'admin_notices' );
|
66 |
-
}
|
67 |
-
|
68 |
-
if ( isset( $_GET['mycred_addons_upgrader'] ) && $_GET['mycred_addons_upgrader'] == 'mycred-addons-updated' ) {
|
69 |
-
|
70 |
-
update_option( 'mycred_addons_upgrade', 'done' );
|
71 |
-
wp_redirect( remove_query_arg( 'mycred_addons_upgrader', home_url( $_SERVER['REQUEST_URI'] ) ) );
|
72 |
-
|
73 |
-
}
|
74 |
-
|
75 |
-
}
|
76 |
-
|
77 |
-
public function update_transient( $data ) {
|
78 |
-
|
79 |
-
if ( empty( $data->checked ) ) return $data;
|
80 |
-
|
81 |
-
if ( isset( $_GET['mautype'] ) && isset( $_GET['plugins'] ) ) {
|
82 |
-
|
83 |
-
$addons = explode( ',', $_GET['plugins'] );
|
84 |
-
|
85 |
-
if ( ! empty( $addons ) && is_array( $addons ) ) {
|
86 |
-
|
87 |
-
$all_installed_plugins = get_plugins();
|
88 |
-
$mycred_installed_addons = $this->get_installed_mycred_addons( $all_installed_plugins );
|
89 |
-
$mycred_addons_detail = (array) $this->get_addons_detail( $mycred_installed_addons );
|
90 |
-
|
91 |
-
foreach ( $addons as $key => $addon ) {
|
92 |
-
|
93 |
-
$addon_slug = explode( '/', $addon );
|
94 |
-
|
95 |
-
if ( ! empty( $addon_slug[0] ) && ! empty( $mycred_addons_detail[ $addon_slug[0] ] ) ) {
|
96 |
-
|
97 |
-
$data->response[ $addon ] = $mycred_addons_detail[ $addon_slug[0] ];
|
98 |
-
|
99 |
-
if ( ! empty( $data->response[ $addon ]->package ) ) {
|
100 |
-
|
101 |
-
$data->response[ $addon ]->package = add_query_arg(
|
102 |
-
array(
|
103 |
-
'site' => site_url(),
|
104 |
-
'api-key' => md5( get_bloginfo( 'url' ) ),
|
105 |
-
'slug' => $data->response[ $addon ]->slug
|
106 |
-
),
|
107 |
-
$data->response[ $addon ]->package
|
108 |
-
);
|
109 |
-
|
110 |
-
$data->no_update[ $addon ] = $data->response[ $addon ];
|
111 |
-
|
112 |
-
}
|
113 |
-
|
114 |
-
}
|
115 |
-
|
116 |
-
}
|
117 |
-
|
118 |
-
}
|
119 |
-
|
120 |
-
}
|
121 |
-
|
122 |
-
return $data;
|
123 |
-
}
|
124 |
-
|
125 |
-
public function update_actions( $update_actions, $plugin_info ) {
|
126 |
-
|
127 |
-
if ( isset( $_GET['mautype'] ) && $_GET['mautype'] == true ) {
|
128 |
-
|
129 |
-
$update_actions['plugins_page'] = sprintf(
|
130 |
-
'<a href="%s" target="_parent">%s</a>',
|
131 |
-
self_admin_url( 'options.php?page=mycred-update' ),
|
132 |
-
__( 'Go to myCred Addons Update page' )
|
133 |
-
);
|
134 |
-
|
135 |
-
$update_actions['updates_page'] = sprintf(
|
136 |
-
'<a href="%s" target="_parent">%s</a>',
|
137 |
-
self_admin_url( 'plugins.php' ),
|
138 |
-
__( 'Go to Plugins page' )
|
139 |
-
);
|
140 |
-
|
141 |
-
}
|
142 |
-
|
143 |
-
update_option( 'mycred_addons_upgrade', 'done' );
|
144 |
-
|
145 |
-
return $update_actions;
|
146 |
-
|
147 |
-
}
|
148 |
-
|
149 |
-
|
150 |
-
public function mycred_addons_update() {
|
151 |
-
|
152 |
-
$all_installed_plugins = get_plugins();
|
153 |
-
$mycred_installed_addons = $this->get_installed_mycred_addons( $all_installed_plugins );
|
154 |
-
$mycred_addons_detail = (array) $this->get_addons_detail( $mycred_installed_addons );
|
155 |
-
|
156 |
-
if ( isset( $_POST['mycred_addons_update'] ) ) {
|
157 |
-
|
158 |
-
delete_site_transient('update_plugins');
|
159 |
-
|
160 |
-
$title = __( 'myCred Addons Update' );
|
161 |
-
|
162 |
-
wp_enqueue_script( 'updates' );
|
163 |
-
$url = self_admin_url( 'update.php?action=update-selected&mautype=true&plugins=' . urlencode( implode( ',', $_POST['mycred_addons_update'] ) ) );
|
164 |
-
$url = wp_nonce_url( $url, 'bulk-update-plugins' );
|
165 |
-
|
166 |
-
?>
|
167 |
-
<div class="wrap">
|
168 |
-
<h1><?php echo esc_html( $title ); ?></h1>
|
169 |
-
<div class="notice notice-warning">
|
170 |
-
<h2 id="mycred-addons-update-msg-title">Please wait for a while! <span class="is-active spinner" style="margin:-6px 10px 0;float: none;"></span></h2>
|
171 |
-
<p>After updating addons, you are required to get a new license key from myCred.me (Dashboard).</p>
|
172 |
-
<p><span style="color:#d63638;font-weight: bold;">Note:</span> If you're facing issues while updating your addons, you can manually update them from <a href="https://mycred.me/redirect-to-membership/" target="_blank">myCred.me (Dashboard).</a><br /><a href="https://mycred.me/blog/why-do-you-need-to-update-your-mycred-addons/" target="_blank">Why am I seeing this notice?</a></p>
|
173 |
-
<a href="https://mycred.me/redirect-to-membership/" target="_blank" class="button button-primary button-large">Get your Updated License Key</a>
|
174 |
-
<br>
|
175 |
-
<br>
|
176 |
-
</div>
|
177 |
-
<iframe id="mycred-addons-update-frame" src="<?php echo $url; ?>" style="width: 100%; height:100%; min-height:850px;"></iframe>
|
178 |
-
</div>
|
179 |
-
<script type="text/javascript">
|
180 |
-
|
181 |
-
jQuery('#mycred-addons-update-frame').on('load', function(){
|
182 |
-
jQuery('#mycred-addons-update-msg-title').hide();
|
183 |
-
});
|
184 |
-
|
185 |
-
</script>
|
186 |
-
<?php
|
187 |
-
}
|
188 |
-
else { ?>
|
189 |
-
<div class="wrap">
|
190 |
-
<h1>myCred Addons Update</h1>
|
191 |
-
<form method="post" name="upgrade-plugins" class="upgrade">
|
192 |
-
<p>
|
193 |
-
<input id="upgrade-plugins" class="button" type="submit" value="Update Plugins" name="upgrade">
|
194 |
-
</p>
|
195 |
-
<table class="widefat updates-table" id="update-plugins-table">
|
196 |
-
<thead>
|
197 |
-
<tr>
|
198 |
-
<td class="manage-column check-column"><input type="checkbox" id="plugins-select-all"></td>
|
199 |
-
<td class="manage-column"><label for="plugins-select-all">Select All</label></td>
|
200 |
-
</tr>
|
201 |
-
</thead>
|
202 |
-
<tbody class="plugins">
|
203 |
-
<?php
|
204 |
-
|
205 |
-
$count = 0;
|
206 |
-
|
207 |
-
foreach ( $mycred_installed_addons as $key => $value ) :
|
208 |
-
|
209 |
-
$addon_slug = explode( '/', $value );
|
210 |
-
|
211 |
-
if ( ! isset( $mycred_addons_detail[ $addon_slug[0] ] ) ) continue;
|
212 |
-
|
213 |
-
$addon = $mycred_addons_detail[ $addon_slug[0] ];
|
214 |
-
|
215 |
-
if ( version_compare( $all_installed_plugins[ $value ]['Version'], $addon->new_version, '>=' ) ) continue;
|
216 |
-
|
217 |
-
$count++;
|
218 |
-
|
219 |
-
?>
|
220 |
-
<tr>
|
221 |
-
<td class="check-column">
|
222 |
-
<input type="checkbox" name="mycred_addons_update[]" id="checkbox_<?php echo $addon_slug[0]; ?>" value="<?php echo $value; ?>">
|
223 |
-
<label for="checkbox_<?php echo $addon_slug[0]; ?>" class="screen-reader-text">Select myCred</label>
|
224 |
-
</td>
|
225 |
-
<td class="plugin-title">
|
226 |
-
<p>
|
227 |
-
<img src="https://mycred.me/wp-content/uploads/2013/02/mycred-token-icon-100x100.png" alt="">
|
228 |
-
<strong><?php echo $addon->name; ?></strong> You have version <?php echo $all_installed_plugins[ $value ]['Version']; ?> installed. Update to <?php echo $addon->new_version ?>.
|
229 |
-
<br>Compatibility with WordPress <?php echo $addon->tested ?>: 100% (according to its author)<br>Improved license system.
|
230 |
-
</p>
|
231 |
-
</td>
|
232 |
-
</tr>
|
233 |
-
<?php endforeach; ?>
|
234 |
-
<?php if ( $count == 0 ): ?>
|
235 |
-
<tr>
|
236 |
-
<td colspan="2">Empty</td>
|
237 |
-
</tr>
|
238 |
-
<?php endif ?>
|
239 |
-
</tbody>
|
240 |
-
<tfoot>
|
241 |
-
<tr>
|
242 |
-
<td class="manage-column check-column"><input type="checkbox" id="plugins-select-all-2"></td>
|
243 |
-
<td class="manage-column"><label for="plugins-select-all-2">Select All</label></td>
|
244 |
-
</tr>
|
245 |
-
</tfoot>
|
246 |
-
</table>
|
247 |
-
<p>
|
248 |
-
<input id="upgrade-plugins-2" class="button" type="submit" value="Update Plugins" name="upgrade">
|
249 |
-
</p>
|
250 |
-
</form>
|
251 |
-
</div>
|
252 |
-
<?php
|
253 |
-
}
|
254 |
-
|
255 |
-
}
|
256 |
-
|
257 |
-
public function get_installed_mycred_addons( $installed_plugins ) {
|
258 |
-
|
259 |
-
$mycred_addons = array(
|
260 |
-
'mycred-2co/mycred-2co.php',
|
261 |
-
'mycred-coinbase/mycred-coinbase.php',
|
262 |
-
'mycred-coinpayment/mycred-coinpayment.php',
|
263 |
-
'mycred-compropago/mycred-compropago.php',
|
264 |
-
'mycred-payfast/mycred-payfast.php',
|
265 |
-
'mycred-paymentwall/mycred-paymentwall.php',
|
266 |
-
'mycred-payza/mycred-payza.php',
|
267 |
-
'mycred-robokassa/mycred-robokassa.php',
|
268 |
-
'mycred-stripe/mycred-stripe.php',
|
269 |
-
'mycred-wepay/mycred-wepay.php',
|
270 |
-
'mycred-cashcred-paypal/mycred-cashcred-paypal.php',
|
271 |
-
'mycred-cashcred-stripe/mycred-cashcred-stripe.php',
|
272 |
-
'mycred-anniversary-pro/mycred-anniversary-pro.php',
|
273 |
-
'mycred-birthday-plus/myCred-birthday-plus.php',
|
274 |
-
'mycred-bp-charges/mycred-bp-charges.php',
|
275 |
-
'mycred-cashcred-paystack/mycred-cashcred-paystack.php',
|
276 |
-
'mycred-coupons-plus/mycred-coupons-plus.php',
|
277 |
-
'mycred-daily-login-rewards/mycred-daily-login-rewards.php',
|
278 |
-
'mycred-dokan/mycred-dokan.php',
|
279 |
-
'mycred-email-digest/mycred-email-digest.php',
|
280 |
-
'mycred-expiration-addon/mycred-expiration-addon.php',
|
281 |
-
'mycred-beaver-builder/mycred-beaver-builder.php',
|
282 |
-
'mycred-userpro/mycred-userpro.php',
|
283 |
-
'mycred-usersultra/mycred-usersultra.php',
|
284 |
-
'mycred-vc/mycred-vc.php',
|
285 |
-
'mycred-gateway-edd/mycred-gateway-edd.php',
|
286 |
-
'mycred-gateway-jigoshop/mycred-gateway-jigoshop.php',
|
287 |
-
'mycred-gateway-fundraising/mycred-gateway-fundraising.php',
|
288 |
-
'mycred-level-cred/mycred-level-cred.php',
|
289 |
-
'mycred-notice-plus/mycred-notice-plus.php',
|
290 |
-
'mycred-pacman/mycred-pacman.php',
|
291 |
-
'mycred-paystack/mycred-paystack.php',
|
292 |
-
'mycred-points-cap/mycred-points-cap.php',
|
293 |
-
'mycred-progress-bar/mycred-progress-bar.php',
|
294 |
-
'mycred-progress-map/mycred-progress-map.php',
|
295 |
-
'mycred-reset-points/mycred-reset-points.php',
|
296 |
-
'mycred-rest/mycred-rest.php',
|
297 |
-
'mycred-sms-payments/mycred-sms-payments.php',
|
298 |
-
'mycred-social-proof/mycred-social-proof.php',
|
299 |
-
'mycred-social-shares/mycred-social-shares.php',
|
300 |
-
'mycred-transfer-plus/mycred-transfer-plus.php',
|
301 |
-
'mycred-videos/mycred-videos.php',
|
302 |
-
'mycred-jwplayer/mycred-jwplayer.php',
|
303 |
-
'mycred-wc-vendor/mycred-wc-vendors-addon.php',
|
304 |
-
'mycred-wheel-of-fortune/mycred-wheel-of-fortune.php',
|
305 |
-
'mycred-woocommerce-plus/mycred-woocommerce-plus.php',
|
306 |
-
'mycred-zapier/mycred-zapier.php'
|
307 |
-
);
|
308 |
-
|
309 |
-
return array_intersect( $mycred_addons, array_keys( $installed_plugins ) );
|
310 |
-
|
311 |
-
}
|
312 |
-
|
313 |
-
public function get_addons_detail( $installed_addons ) {
|
314 |
-
|
315 |
-
$transient_key = md5( implode( ",", $installed_addons ) );
|
316 |
-
$plugins_data = get_site_transient( $transient_key );
|
317 |
-
|
318 |
-
if ( false === $plugins_data ) {
|
319 |
-
|
320 |
-
$addons = array();
|
321 |
-
|
322 |
-
foreach ( $installed_addons as $key => $addon ) {
|
323 |
-
|
324 |
-
$addon_file = explode( '/', $addon );
|
325 |
-
|
326 |
-
if ( ! empty( $addon_file[0] ) ) array_push( $addons, $addon_file[0] );
|
327 |
-
|
328 |
-
}
|
329 |
-
|
330 |
-
$plugins_data = new stdClass();
|
331 |
-
$request_args = array(
|
332 |
-
'body' => array(
|
333 |
-
'site' => site_url(),
|
334 |
-
'api-key' => md5( get_bloginfo( 'url' ) ),
|
335 |
-
'addons' => $addons
|
336 |
-
),
|
337 |
-
'timeout' => 12
|
338 |
-
);
|
339 |
-
|
340 |
-
// Start checking for an update
|
341 |
-
$response = wp_remote_post( 'https://license.mycred.me/wp-json/license/get-new-plugins', $request_args );
|
342 |
-
|
343 |
-
if ( ! is_wp_error( $response ) ) {
|
344 |
-
|
345 |
-
$response_data = json_decode( $response['body'] );
|
346 |
-
|
347 |
-
if ( ! empty( $response_data->status ) && $response_data->status == 'success' ) {
|
348 |
-
|
349 |
-
$plugins_data = $response_data->data;
|
350 |
-
set_site_transient( $transient_key, $plugins_data, 5 * HOUR_IN_SECONDS );
|
351 |
-
|
352 |
-
}
|
353 |
-
|
354 |
-
}
|
355 |
-
|
356 |
-
}
|
357 |
-
|
358 |
-
return $plugins_data;
|
359 |
-
|
360 |
-
}
|
361 |
-
|
362 |
-
}
|
363 |
-
endif;
|
364 |
-
|
365 |
-
new myCRED_Addons_Upgrader();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -21,15 +21,15 @@ if (! function_exists('mycred_render_shortcode_video') ) :
|
|
21 |
extract(
|
22 |
shortcode_atts(
|
23 |
array(
|
24 |
-
'id'
|
25 |
-
'width'
|
26 |
-
'height'
|
27 |
-
'amount'
|
28 |
-
'logic'
|
29 |
-
'interval'
|
30 |
-
'streaming'
|
31 |
-
'duration'
|
32 |
-
'ctype'
|
33 |
), $atts, MYCRED_SLUG . '_video'
|
34 |
)
|
35 |
);
|
@@ -114,7 +114,7 @@ if (! function_exists('mycred_render_shortcode_video') ) :
|
|
114 |
?>
|
115 |
<div class="row mycred-video-wrapper youtube-video">
|
116 |
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
117 |
-
<iframe id="mycred_vvideo_v<?php echo $video_id; ?>" class="mycred-video mycred-youtube-video" data-vid="<?php echo $video_id; ?>" src="<?php echo esc_url($url); ?>" width="<?php echo $width; ?>" height="<?php echo $height; ?>" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
118 |
</div>
|
119 |
</div>
|
120 |
<?php
|
21 |
extract(
|
22 |
shortcode_atts(
|
23 |
array(
|
24 |
+
'id' => null,
|
25 |
+
'width' => 560,
|
26 |
+
'height' => 315,
|
27 |
+
'amount' => '',
|
28 |
+
'logic' => '',
|
29 |
+
'interval' => '',
|
30 |
+
'streaming' => '',
|
31 |
+
'duration' => '',
|
32 |
+
'ctype' => MYCRED_DEFAULT_TYPE_KEY
|
33 |
), $atts, MYCRED_SLUG . '_video'
|
34 |
)
|
35 |
);
|
114 |
?>
|
115 |
<div class="row mycred-video-wrapper youtube-video">
|
116 |
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
117 |
+
<iframe id="mycred_vvideo_v<?php echo esc_attr($video_id); ?>" class="mycred-video mycred-youtube-video" data-vid="<?php echo esc_attr($video_id); ?>" src="<?php echo esc_url($url); ?>" width="<?php echo esc_attr($width); ?>" height="<?php echo esc_attr($height); ?>" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
118 |
</div>
|
119 |
</div>
|
120 |
<?php
|