Customer reports
This commit is contained in:
parent
aa41255596
commit
1c1d60b375
|
@ -60,6 +60,7 @@ class WC_Admin_Reports {
|
|||
wp_enqueue_script( 'flot-resize', WC()->plugin_url() . '/assets/js/admin/jquery.flot.resize' . $suffix . '.js', array('jquery', 'flot'), '1.0' );
|
||||
wp_enqueue_script( 'flot-time', WC()->plugin_url() . '/assets/js/admin/jquery.flot.time' . $suffix . '.js', array( 'jquery', 'flot' ), '1.0' );
|
||||
wp_enqueue_script( 'flot-pie', WC()->plugin_url() . '/assets/js/admin/jquery.flot.pie' . $suffix . '.js', array( 'jquery', 'flot' ), '1.0' );
|
||||
wp_enqueue_script( 'flot-stack', WC()->plugin_url() . '/assets/js/admin/jquery.flot.stack' . $suffix . '.js', array( 'jquery', 'flot' ), '1.0' );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,11 +103,11 @@ class WC_Admin_Reports {
|
|||
'customers' => array(
|
||||
'title' => __( 'Customers', 'woocommerce' ),
|
||||
'reports' => array(
|
||||
"overview" => array(
|
||||
"customers" => array(
|
||||
'title' => __( 'Overview', 'woocommerce' ),
|
||||
'description' => '',
|
||||
'hide_title' => true,
|
||||
'callback' => 'woocommerce_customer_overview'
|
||||
'callback' => array( $this, 'get_report' )
|
||||
),
|
||||
)
|
||||
),
|
||||
|
@ -554,206 +555,24 @@ function woocommerce_customer_overview() {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output the stock overview stats.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function woocommerce_stock_overview() {
|
||||
|
||||
global $start_date, $end_date, $woocommerce, $wpdb;
|
||||
|
||||
// Low/No stock lists
|
||||
$lowstockamount = get_option('woocommerce_notify_low_stock_amount');
|
||||
if (!is_numeric($lowstockamount)) $lowstockamount = 1;
|
||||
|
||||
$nostockamount = get_option('woocommerce_notify_no_stock_amount');
|
||||
if (!is_numeric($nostockamount)) $nostockamount = 0;
|
||||
|
||||
// Get low in stock simple/downloadable/virtual products. Grouped don't have stock. Variations need a separate query.
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => '_manage_stock',
|
||||
'value' => 'yes'
|
||||
),
|
||||
array(
|
||||
'key' => '_stock',
|
||||
'value' => $lowstockamount,
|
||||
'compare' => '<=',
|
||||
'type' => 'NUMERIC'
|
||||
)
|
||||
),
|
||||
'tax_query' => array(
|
||||
array(
|
||||
'taxonomy' => 'product_type',
|
||||
'field' => 'name',
|
||||
'terms' => array('simple'),
|
||||
'operator' => 'IN'
|
||||
)
|
||||
),
|
||||
'fields' => 'id=>parent'
|
||||
);
|
||||
|
||||
$low_stock_products = (array) get_posts($args);
|
||||
|
||||
// Get low stock product variations
|
||||
$args = array(
|
||||
'post_type' => 'product_variation',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => '_stock',
|
||||
'value' => $lowstockamount,
|
||||
'compare' => '<=',
|
||||
'type' => 'NUMERIC'
|
||||
),
|
||||
array(
|
||||
'key' => '_stock',
|
||||
'value' => array( '', false, null ),
|
||||
'compare' => 'NOT IN'
|
||||
)
|
||||
),
|
||||
'fields' => 'id=>parent'
|
||||
);
|
||||
|
||||
$low_stock_variations = (array) get_posts($args);
|
||||
|
||||
// Get low stock variable products (where stock is set for the parent)
|
||||
$args = array(
|
||||
'post_type' => array('product'),
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'meta_query' => array(
|
||||
'relation' => 'AND',
|
||||
array(
|
||||
'key' => '_manage_stock',
|
||||
'value' => 'yes'
|
||||
),
|
||||
array(
|
||||
'key' => '_stock',
|
||||
'value' => $lowstockamount,
|
||||
'compare' => '<=',
|
||||
'type' => 'NUMERIC'
|
||||
)
|
||||
),
|
||||
'tax_query' => array(
|
||||
array(
|
||||
'taxonomy' => 'product_type',
|
||||
'field' => 'name',
|
||||
'terms' => array('variable'),
|
||||
'operator' => 'IN'
|
||||
)
|
||||
),
|
||||
'fields' => 'id=>parent'
|
||||
);
|
||||
|
||||
$low_stock_variable_products = (array) get_posts($args);
|
||||
|
||||
// Get products marked out of stock
|
||||
$args = array(
|
||||
'post_type' => array( 'product' ),
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'meta_query' => array(
|
||||
'relation' => 'AND',
|
||||
array(
|
||||
'key' => '_stock_status',
|
||||
'value' => 'outofstock'
|
||||
)
|
||||
),
|
||||
'fields' => 'id=>parent'
|
||||
);
|
||||
|
||||
$out_of_stock_status_products = (array) get_posts($args);
|
||||
|
||||
// Merge results
|
||||
$low_in_stock = apply_filters( 'woocommerce_reports_stock_overview_products', $low_stock_products + $low_stock_variations + $low_stock_variable_products + $out_of_stock_status_products );
|
||||
?>
|
||||
<div id="poststuff" class="woocommerce-reports-wrap halved">
|
||||
<div class="woocommerce-reports-left">
|
||||
<div class="postbox">
|
||||
<h3><span><?php _e( 'Low stock', 'woocommerce' ); ?></span></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
if ( $low_in_stock ) {
|
||||
echo '<ul class="stock_list">';
|
||||
foreach ( $low_in_stock as $product_id => $parent ) {
|
||||
|
||||
$stock = (int) get_post_meta( $product_id, '_stock', true );
|
||||
$sku = get_post_meta( $product_id, '_sku', true );
|
||||
|
||||
if ( $stock <= $nostockamount || in_array( $product_id, array_keys( $out_of_stock_status_products ) ) )
|
||||
continue;
|
||||
|
||||
$title = esc_html__( get_the_title( $product_id ) );
|
||||
|
||||
if ( $sku )
|
||||
$title .= ' (' . __( 'SKU', 'woocommerce' ) . ': ' . esc_html( $sku ) . ')';
|
||||
|
||||
if ( get_post_type( $product_id ) == 'product' )
|
||||
$product_url = admin_url( 'post.php?post=' . $product_id . '&action=edit' );
|
||||
else
|
||||
$product_url = admin_url( 'post.php?post=' . $parent . '&action=edit' );
|
||||
|
||||
printf( '<li><a href="%s"><small>' . _n('%d in stock', '%d in stock', $stock, 'woocommerce') . '</small> %s</a></li>', $product_url, $stock, $title );
|
||||
|
||||
}
|
||||
echo '</ul>';
|
||||
} else {
|
||||
echo '<p>'.__( 'No products are low in stock.', 'woocommerce' ).'</p>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="woocommerce-reports-right">
|
||||
<div class="postbox">
|
||||
<h3><span><?php _e( 'Out of stock', 'woocommerce' ); ?></span></h3>
|
||||
<div class="inside">
|
||||
<?php
|
||||
if ( $low_in_stock ) {
|
||||
echo '<ul class="stock_list">';
|
||||
foreach ( $low_in_stock as $product_id => $parent ) {
|
||||
|
||||
$stock = get_post_meta( $product_id, '_stock', true );
|
||||
$sku = get_post_meta( $product_id, '_sku', true );
|
||||
|
||||
if ( $stock > $nostockamount && ! in_array( $product_id, array_keys( $out_of_stock_status_products ) ) )
|
||||
continue;
|
||||
|
||||
$title = esc_html__( get_the_title( $product_id ) );
|
||||
|
||||
if ( $sku )
|
||||
$title .= ' (' . __( 'SKU', 'woocommerce' ) . ': ' . esc_html( $sku ) . ')';
|
||||
|
||||
if ( get_post_type( $product_id ) == 'product' )
|
||||
$product_url = admin_url( 'post.php?post=' . $product_id . '&action=edit' );
|
||||
else
|
||||
$product_url = admin_url( 'post.php?post=' . $parent . '&action=edit' );
|
||||
|
||||
if ( $stock == '' )
|
||||
printf( '<li><a href="%s"><small>' . __('Marked out of stock', 'woocommerce') . '</small> %s</a></li>', $product_url, $title );
|
||||
else
|
||||
printf( '<li><a href="%s"><small>' . _n('%d in stock', '%d in stock', $stock, 'woocommerce') . '</small> %s</a></li>', $product_url, $stock, $title );
|
||||
|
||||
}
|
||||
echo '</ul>';
|
||||
} else {
|
||||
echo '<p>'.__( 'No products are out in stock.', 'woocommerce' ).'</p>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -269,7 +269,10 @@ class WC_Admin_Report {
|
|||
if ( ! isset( $prepared_data[ $time ] ) )
|
||||
continue;
|
||||
|
||||
$prepared_data[ $time ][1] += $d->$data_key;
|
||||
if ( $data_key )
|
||||
$prepared_data[ $time ][1] += $d->$data_key;
|
||||
else
|
||||
$prepared_data[ $time ][1] ++;
|
||||
}
|
||||
|
||||
return $prepared_data;
|
||||
|
|
|
@ -101,7 +101,7 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
|
|||
switch ( $current_range ) {
|
||||
case 'custom' :
|
||||
$this->start_date = strtotime( sanitize_text_field( $_GET['start_date'] ) );
|
||||
$this->end_date = strtotime( 'midnight', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
|
||||
if ( ! $this->end_date )
|
||||
$this->end_date = current_time('timestamp');
|
||||
|
@ -120,7 +120,7 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
|
|||
break;
|
||||
case 'year' :
|
||||
$this->start_date = strtotime( 'first day of january', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'month';
|
||||
break;
|
||||
case 'last_month' :
|
||||
|
@ -130,13 +130,13 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
|
|||
break;
|
||||
case 'month' :
|
||||
$this->start_date = strtotime( 'first day of this month', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
case '7day' :
|
||||
default :
|
||||
$this->start_date = strtotime( 'midnight -6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->start_date = strtotime( '-6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
}
|
||||
|
@ -460,9 +460,6 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
|
|||
legend: {
|
||||
show: false
|
||||
},
|
||||
series: {
|
||||
stack: true
|
||||
},
|
||||
grid: {
|
||||
color: '#aaa',
|
||||
borderColor: 'transparent',
|
||||
|
|
|
@ -0,0 +1,391 @@
|
|||
<?php
|
||||
/**
|
||||
* WC_Report_Customers class
|
||||
*/
|
||||
class WC_Report_Customers extends WC_Admin_Report {
|
||||
|
||||
/**
|
||||
* Get the legend for the main chart sidebar
|
||||
* @return array
|
||||
*/
|
||||
public function get_chart_legend() {
|
||||
$legend = array();
|
||||
|
||||
$legend[] = array(
|
||||
'title' => sprintf( __( '%s signups in this period', 'woocommerce' ), '<strong>' . sizeof( $this->customers ) . '</strong>' ),
|
||||
'color' => $this->chart_colours['signups']
|
||||
);
|
||||
|
||||
return $legend;
|
||||
}
|
||||
|
||||
/**
|
||||
* [get_chart_widgets description]
|
||||
* @return array
|
||||
*/
|
||||
public function get_chart_widgets() {
|
||||
$widgets = array();
|
||||
|
||||
$widgets[] = array(
|
||||
'title' => '',
|
||||
'callback' => array( $this, 'customers_vs_guests' )
|
||||
);
|
||||
|
||||
return $widgets;
|
||||
}
|
||||
|
||||
/**
|
||||
* customers_vs_guests
|
||||
* @return void
|
||||
*/
|
||||
public function customers_vs_guests() {
|
||||
|
||||
$customer_order_totals = $this->get_order_report_data( array(
|
||||
'data' => array(
|
||||
'ID' => array(
|
||||
'type' => 'post_data',
|
||||
'function' => 'COUNT',
|
||||
'name' => 'total_orders'
|
||||
)
|
||||
),
|
||||
'where_meta' => array(
|
||||
array(
|
||||
'meta_key' => '_customer_user',
|
||||
'meta_value' => '0',
|
||||
'operator' => '>'
|
||||
)
|
||||
),
|
||||
'filter_range' => true
|
||||
) );
|
||||
|
||||
$guest_order_totals = $this->get_order_report_data( array(
|
||||
'data' => array(
|
||||
'ID' => array(
|
||||
'type' => 'post_data',
|
||||
'function' => 'COUNT',
|
||||
'name' => 'total_orders'
|
||||
)
|
||||
),
|
||||
'where_meta' => array(
|
||||
array(
|
||||
'meta_key' => '_customer_user',
|
||||
'meta_value' => '0',
|
||||
'operator' => '='
|
||||
)
|
||||
),
|
||||
'filter_range' => true
|
||||
) );
|
||||
?>
|
||||
<div class="chart-container">
|
||||
<div class="chart-placeholder customers_vs_guests pie-chart" style="height:200px"></div>
|
||||
<ul class="pie-chart-legend">
|
||||
<li style="border-color: <?php echo $this->chart_colours['customers']; ?>"><?php _e( 'Customer Sales', 'woocommerce' ); ?></li>
|
||||
<li style="border-color: <?php echo $this->chart_colours['guests']; ?>"><?php _e( 'Guest Sales', 'woocommerce' ); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
jQuery(function(){
|
||||
jQuery.plot(
|
||||
jQuery('.chart-placeholder.customers_vs_guests'),
|
||||
[
|
||||
{
|
||||
label: '<?php _e( 'Customer Orders', 'woocommerce' ); ?>',
|
||||
data: "<?php echo $customer_order_totals->total_orders ?>",
|
||||
color: '<?php echo $this->chart_colours['customers']; ?>'
|
||||
},
|
||||
{
|
||||
label: '<?php _e( 'Guest Orders', 'woocommerce' ); ?>',
|
||||
data: "<?php echo $guest_order_totals->total_orders ?>",
|
||||
color: '<?php echo $this->chart_colours['guests']; ?>'
|
||||
}
|
||||
],
|
||||
{
|
||||
grid: {
|
||||
hoverable: true
|
||||
},
|
||||
series: {
|
||||
pie: {
|
||||
show: true,
|
||||
radius: 1,
|
||||
innerRadius: 0.6,
|
||||
label: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
enable_tooltip: true,
|
||||
append_tooltip: "<?php echo ' ' . __( 'orders', 'woocommerce' ); ?>",
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
jQuery('.chart-placeholder.customers_vs_guests').resize();
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the report
|
||||
*/
|
||||
public function output_report() {
|
||||
global $woocommerce, $wpdb, $wp_locale;
|
||||
|
||||
$ranges = array(
|
||||
'year' => __( 'Year', 'woocommerce' ),
|
||||
'last_month' => __( 'Last Month', 'woocommerce' ),
|
||||
'month' => __( 'This Month', 'woocommerce' ),
|
||||
'7day' => __( 'Last 7 Days', 'woocommerce' )
|
||||
);
|
||||
|
||||
$this->chart_colours = array(
|
||||
'signups' => '#3498db',
|
||||
'customers' => '#1abc9c',
|
||||
'guests' => '#8fdece'
|
||||
);
|
||||
|
||||
$current_range = ! empty( $_GET['range'] ) ? $_GET['range'] : '7day';
|
||||
|
||||
switch ( $current_range ) {
|
||||
case 'custom' :
|
||||
$this->start_date = strtotime( sanitize_text_field( $_GET['start_date'] ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
|
||||
if ( ! $this->end_date )
|
||||
$this->end_date = current_time('timestamp');
|
||||
|
||||
$interval = 0;
|
||||
$min_date = $this->start_date;
|
||||
while ( ( $min_date = strtotime( "+1 MONTH", $min_date ) ) <= $this->end_date ) {
|
||||
$interval ++;
|
||||
}
|
||||
|
||||
// 3 months max for day view
|
||||
if ( $interval > 3 )
|
||||
$this->chart_groupby = 'month';
|
||||
else
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
case 'year' :
|
||||
$this->start_date = strtotime( 'first day of january', current_time('timestamp') );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'month';
|
||||
break;
|
||||
case 'last_month' :
|
||||
$this->start_date = strtotime( 'first day of last month', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'last day of last month', current_time('timestamp') );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
case 'month' :
|
||||
$this->start_date = strtotime( 'first day of this month', current_time('timestamp') );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
case '7day' :
|
||||
default :
|
||||
$this->start_date = strtotime( '-6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
}
|
||||
|
||||
// Group by
|
||||
switch ( $this->chart_groupby ) {
|
||||
case 'day' :
|
||||
$this->group_by_query = 'YEAR(post_date), MONTH(post_date), DAY(post_date)';
|
||||
$this->chart_interval = max( 0, ( $this->end_date - $this->start_date ) / ( 60 * 60 * 24 ) );
|
||||
$this->barwidth = 60 * 60 * 24 * 1000;
|
||||
break;
|
||||
case 'month' :
|
||||
$this->group_by_query = 'YEAR(post_date), MONTH(post_date)';
|
||||
$this->chart_interval = 0;
|
||||
$min_date = $this->start_date;
|
||||
while ( ( $min_date = strtotime( "+1 MONTH", $min_date ) ) <= $this->end_date ) {
|
||||
$this->chart_interval ++;
|
||||
}
|
||||
$this->barwidth = 60 * 60 * 24 * 7 * 4 * 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
$admin_users = new WP_User_Query(
|
||||
array(
|
||||
'role' => 'administrator',
|
||||
'fields' => 'ID'
|
||||
)
|
||||
);
|
||||
|
||||
$manager_users = new WP_User_Query(
|
||||
array(
|
||||
'role' => 'shop_manager',
|
||||
'fields' => 'ID'
|
||||
)
|
||||
);
|
||||
|
||||
$users_query = new WP_User_Query(
|
||||
array(
|
||||
'fields' => array( 'user_registered' ),
|
||||
'exclude' => array_merge( $admin_users->get_results(), $manager_users->get_results() )
|
||||
)
|
||||
);
|
||||
|
||||
$this->customers = $users_query->get_results();
|
||||
|
||||
include( WC()->plugin_path() . '/admin/views/html-report-by-date.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the main chart
|
||||
* @return string
|
||||
*/
|
||||
public function get_main_chart() {
|
||||
global $wp_locale;
|
||||
|
||||
$customer_orders = $this->get_order_report_data( array(
|
||||
'data' => array(
|
||||
'ID' => array(
|
||||
'type' => 'post_data',
|
||||
'function' => 'COUNT',
|
||||
'name' => 'total_orders'
|
||||
),
|
||||
'post_date' => array(
|
||||
'type' => 'post_data',
|
||||
'function' => '',
|
||||
'name' => 'post_date'
|
||||
),
|
||||
),
|
||||
'where_meta' => array(
|
||||
array(
|
||||
'meta_key' => '_customer_user',
|
||||
'meta_value' => '0',
|
||||
'operator' => '>'
|
||||
)
|
||||
),
|
||||
'group_by' => $this->group_by_query,
|
||||
'order_by' => 'post_date ASC',
|
||||
'query_type' => 'get_results',
|
||||
'filter_range' => true
|
||||
) );
|
||||
|
||||
$guest_orders = $this->get_order_report_data( array(
|
||||
'data' => array(
|
||||
'ID' => array(
|
||||
'type' => 'post_data',
|
||||
'function' => 'COUNT',
|
||||
'name' => 'total_orders'
|
||||
),
|
||||
'post_date' => array(
|
||||
'type' => 'post_data',
|
||||
'function' => '',
|
||||
'name' => 'post_date'
|
||||
),
|
||||
),
|
||||
'where_meta' => array(
|
||||
array(
|
||||
'meta_key' => '_customer_user',
|
||||
'meta_value' => '0',
|
||||
'operator' => '='
|
||||
)
|
||||
),
|
||||
'group_by' => $this->group_by_query,
|
||||
'order_by' => 'post_date ASC',
|
||||
'query_type' => 'get_results',
|
||||
'filter_range' => true
|
||||
) );
|
||||
|
||||
$signups = $this->prepare_chart_data( $this->customers, 'user_registered', '', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
||||
$customer_orders = $this->prepare_chart_data( $customer_orders, 'post_date', 'total_orders', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
||||
$guest_orders = $this->prepare_chart_data( $guest_orders, 'post_date', 'total_orders', $this->chart_interval, $this->start_date, $this->chart_groupby );
|
||||
|
||||
// Encode in json format
|
||||
$chart_data = json_encode( array(
|
||||
'signups' => array_values( $signups ),
|
||||
'customer_orders' => array_values( $customer_orders ),
|
||||
'guest_orders' => array_values( $guest_orders )
|
||||
) );
|
||||
?>
|
||||
<div class="chart-container">
|
||||
<div class="chart-placeholder main"></div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
jQuery(function(){
|
||||
var chart_data = jQuery.parseJSON( '<?php echo $chart_data; ?>' );
|
||||
|
||||
jQuery.plot(
|
||||
jQuery('.chart-placeholder.main'),
|
||||
[
|
||||
{
|
||||
label: "<?php echo esc_js( __( 'Customer Orders', 'woocommerce' ) ) ?>",
|
||||
data: chart_data.customer_orders,
|
||||
color: '<?php echo $this->chart_colours['customers']; ?>',
|
||||
bars: { fillColor: '<?php echo $this->chart_colours['customers']; ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo $this->barwidth; ?> * 0.5, align: 'center' },
|
||||
shadowSize: 0,
|
||||
enable_tooltip: true,
|
||||
append_tooltip: "<?php echo ' ' . __( 'customer orders', 'woocommerce' ); ?>",
|
||||
stack: true,
|
||||
},
|
||||
{
|
||||
label: "<?php echo esc_js( __( 'Guest Orders', 'woocommerce' ) ) ?>",
|
||||
data: chart_data.guest_orders,
|
||||
color: '<?php echo $this->chart_colours['guests']; ?>',
|
||||
bars: { fillColor: '<?php echo $this->chart_colours['guests']; ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo $this->barwidth; ?> * 0.5, align: 'center' },
|
||||
shadowSize: 0,
|
||||
enable_tooltip: true,
|
||||
append_tooltip: "<?php echo ' ' . __( 'guest orders', 'woocommerce' ); ?>",
|
||||
stack: true,
|
||||
},
|
||||
{
|
||||
label: "<?php echo esc_js( __( 'Signups', 'woocommerce' ) ) ?>",
|
||||
data: chart_data.signups,
|
||||
color: '<?php echo $this->chart_colours['signups']; ?>',
|
||||
points: { show: true, radius: 5, lineWidth: 3, fillColor: '#fff', fill: true },
|
||||
lines: { show: true, lineWidth: 4, fill: false },
|
||||
shadowSize: 0,
|
||||
enable_tooltip: true,
|
||||
append_tooltip: "<?php echo ' ' . __( 'new users', 'woocommerce' ); ?>",
|
||||
stack: false
|
||||
},
|
||||
],
|
||||
{
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
grid: {
|
||||
color: '#aaa',
|
||||
borderColor: 'transparent',
|
||||
borderWidth: 0,
|
||||
hoverable: true
|
||||
},
|
||||
xaxes: [ {
|
||||
color: '#aaa',
|
||||
position: "bottom",
|
||||
tickColor: 'transparent',
|
||||
mode: "time",
|
||||
timeformat: "<?php if ( $this->chart_groupby == 'day' ) echo '%d %b'; else echo '%b'; ?>",
|
||||
monthNames: <?php echo json_encode( array_values( $wp_locale->month_abbrev ) ) ?>,
|
||||
tickLength: 1,
|
||||
minTickSize: [1, "<?php echo $this->chart_groupby; ?>"],
|
||||
tickSize: [1, "<?php echo $this->chart_groupby; ?>"],
|
||||
font: {
|
||||
color: "#aaa"
|
||||
}
|
||||
} ],
|
||||
yaxes: [
|
||||
{
|
||||
min: 0,
|
||||
minTickSize: 1,
|
||||
tickDecimals: 0,
|
||||
color: '#ecf0f1',
|
||||
font: { color: "#aaa" }
|
||||
}
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
jQuery('.chart-placeholder.main').resize();
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
|
@ -74,7 +74,7 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
|
|||
switch ( $current_range ) {
|
||||
case 'custom' :
|
||||
$this->start_date = strtotime( sanitize_text_field( $_GET['start_date'] ) );
|
||||
$this->end_date = strtotime( 'midnight', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
|
||||
if ( ! $this->end_date )
|
||||
$this->end_date = current_time('timestamp');
|
||||
|
@ -93,7 +93,7 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
|
|||
break;
|
||||
case 'year' :
|
||||
$this->start_date = strtotime( 'first day of january', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'month';
|
||||
break;
|
||||
case 'last_month' :
|
||||
|
@ -103,13 +103,13 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
|
|||
break;
|
||||
case 'month' :
|
||||
$this->start_date = strtotime( 'first day of this month', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
case '7day' :
|
||||
default :
|
||||
$this->start_date = strtotime( 'midnight -6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->start_date = strtotime( '-6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report {
|
|||
switch ( $current_range ) {
|
||||
case 'custom' :
|
||||
$this->start_date = strtotime( sanitize_text_field( $_GET['start_date'] ) );
|
||||
$this->end_date = strtotime( 'midnight', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
|
||||
if ( ! $this->end_date )
|
||||
$this->end_date = current_time('timestamp');
|
||||
|
@ -152,7 +152,7 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report {
|
|||
break;
|
||||
case 'year' :
|
||||
$this->start_date = strtotime( 'first day of january', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'month';
|
||||
break;
|
||||
case 'last_month' :
|
||||
|
@ -162,13 +162,13 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report {
|
|||
break;
|
||||
case 'month' :
|
||||
$this->start_date = strtotime( 'first day of this month', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
case '7day' :
|
||||
default :
|
||||
$this->start_date = strtotime( 'midnight -6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->start_date = strtotime( '-6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report {
|
|||
switch ( $this->chart_groupby ) {
|
||||
case 'day' :
|
||||
$this->group_by_query = 'YEAR(post_date), MONTH(post_date), DAY(post_date)';
|
||||
$this->chart_interval = max( 0, ( $this->end_date - $this->start_date ) / ( 60 * 60 * 24 ) );
|
||||
$this->chart_interval = max( 0, ( $this->end_date - $this->start_date ) / ( 60 * 60 * 24 ) );
|
||||
$this->barwidth = 60 * 60 * 24 * 1000;
|
||||
break;
|
||||
case 'month' :
|
||||
|
@ -380,9 +380,6 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report {
|
|||
legend: {
|
||||
show: false
|
||||
},
|
||||
series: {
|
||||
stack: true
|
||||
},
|
||||
grid: {
|
||||
color: '#aaa',
|
||||
borderColor: 'transparent',
|
||||
|
|
|
@ -102,7 +102,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
|
|||
switch ( $current_range ) {
|
||||
case 'custom' :
|
||||
$this->start_date = strtotime( sanitize_text_field( $_GET['start_date'] ) );
|
||||
$this->end_date = strtotime( 'midnight', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
|
||||
|
||||
if ( ! $this->end_date )
|
||||
$this->end_date = current_time('timestamp');
|
||||
|
@ -121,7 +121,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
|
|||
break;
|
||||
case 'year' :
|
||||
$this->start_date = strtotime( 'first day of january', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'month';
|
||||
break;
|
||||
case 'last_month' :
|
||||
|
@ -131,13 +131,13 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
|
|||
break;
|
||||
case 'month' :
|
||||
$this->start_date = strtotime( 'first day of this month', current_time('timestamp') );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
case '7day' :
|
||||
default :
|
||||
$this->start_date = strtotime( 'midnight -6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( 'midnight', current_time( 'timestamp' ) );
|
||||
$this->start_date = strtotime( '-6 days', current_time( 'timestamp' ) );
|
||||
$this->end_date = strtotime( '12am + 1 day', current_time( 'timestamp' ) );
|
||||
$this->chart_groupby = 'day';
|
||||
break;
|
||||
}
|
||||
|
@ -460,9 +460,6 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
|
|||
legend: {
|
||||
show: false
|
||||
},
|
||||
series: {
|
||||
stack: true
|
||||
},
|
||||
grid: {
|
||||
color: '#aaa',
|
||||
borderColor: 'transparent',
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -2765,6 +2765,21 @@ img.ui-datepicker-trigger { vertical-align: middle; margin-top: -1px; cursor: po
|
|||
box-shadow: 0px 1px 2px rgba(0,0,0,.1);
|
||||
}
|
||||
}
|
||||
.pie-chart-legend {
|
||||
margin: 12px 0 0 0;
|
||||
overflow: hidden;
|
||||
li {
|
||||
float: left;
|
||||
margin: 0;
|
||||
padding: 6px 0 0 0;
|
||||
border-top: 4px solid #999;
|
||||
text-align: center;
|
||||
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
|
||||
-moz-box-sizing: border-box; /* Firefox, other Gecko */
|
||||
box-sizing: border-box; /* Opera/IE 8+ */
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
.stat {
|
||||
font-size: 1.5em !important;
|
||||
font-weight: bold;
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
/* Flot plugin for stacking data sets rather than overlyaing them.
|
||||
|
||||
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
The plugin assumes the data is sorted on x (or y if stacking horizontally).
|
||||
For line charts, it is assumed that if a line has an undefined gap (from a
|
||||
null point), then the line above it should have the same gap - insert zeros
|
||||
instead of "null" if you want another behaviour. This also holds for the start
|
||||
and end of the chart. Note that stacking a mix of positive and negative values
|
||||
in most instances doesn't make sense (so it looks weird).
|
||||
|
||||
Two or more series are stacked when their "stack" attribute is set to the same
|
||||
key (which can be any number or string or just "true"). To specify the default
|
||||
stack, you can set the stack option like this:
|
||||
|
||||
series: {
|
||||
stack: null/false, true, or a key (number/string)
|
||||
}
|
||||
|
||||
You can also specify it for a single series, like this:
|
||||
|
||||
$.plot( $("#placeholder"), [{
|
||||
data: [ ... ],
|
||||
stack: true
|
||||
}])
|
||||
|
||||
The stacking order is determined by the order of the data series in the array
|
||||
(later series end up on top of the previous).
|
||||
|
||||
Internally, the plugin modifies the datapoints in each series, adding an
|
||||
offset to the y value. For line series, extra data points are inserted through
|
||||
interpolation. If there's a second y value, it's also adjusted (e.g for bar
|
||||
charts or filled areas).
|
||||
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
var options = {
|
||||
series: { stack: null } // or number/string
|
||||
};
|
||||
|
||||
function init(plot) {
|
||||
function findMatchingSeries(s, allseries) {
|
||||
var res = null;
|
||||
for (var i = 0; i < allseries.length; ++i) {
|
||||
if (s == allseries[i])
|
||||
break;
|
||||
|
||||
if (allseries[i].stack == s.stack)
|
||||
res = allseries[i];
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function stackData(plot, s, datapoints) {
|
||||
if (s.stack == null || s.stack === false)
|
||||
return;
|
||||
|
||||
var other = findMatchingSeries(s, plot.getData());
|
||||
if (!other)
|
||||
return;
|
||||
|
||||
var ps = datapoints.pointsize,
|
||||
points = datapoints.points,
|
||||
otherps = other.datapoints.pointsize,
|
||||
otherpoints = other.datapoints.points,
|
||||
newpoints = [],
|
||||
px, py, intery, qx, qy, bottom,
|
||||
withlines = s.lines.show,
|
||||
horizontal = s.bars.horizontal,
|
||||
withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
|
||||
withsteps = withlines && s.lines.steps,
|
||||
fromgap = true,
|
||||
keyOffset = horizontal ? 1 : 0,
|
||||
accumulateOffset = horizontal ? 0 : 1,
|
||||
i = 0, j = 0, l, m;
|
||||
|
||||
while (true) {
|
||||
if (i >= points.length)
|
||||
break;
|
||||
|
||||
l = newpoints.length;
|
||||
|
||||
if (points[i] == null) {
|
||||
// copy gaps
|
||||
for (m = 0; m < ps; ++m)
|
||||
newpoints.push(points[i + m]);
|
||||
i += ps;
|
||||
}
|
||||
else if (j >= otherpoints.length) {
|
||||
// for lines, we can't use the rest of the points
|
||||
if (!withlines) {
|
||||
for (m = 0; m < ps; ++m)
|
||||
newpoints.push(points[i + m]);
|
||||
}
|
||||
i += ps;
|
||||
}
|
||||
else if (otherpoints[j] == null) {
|
||||
// oops, got a gap
|
||||
for (m = 0; m < ps; ++m)
|
||||
newpoints.push(null);
|
||||
fromgap = true;
|
||||
j += otherps;
|
||||
}
|
||||
else {
|
||||
// cases where we actually got two points
|
||||
px = points[i + keyOffset];
|
||||
py = points[i + accumulateOffset];
|
||||
qx = otherpoints[j + keyOffset];
|
||||
qy = otherpoints[j + accumulateOffset];
|
||||
bottom = 0;
|
||||
|
||||
if (px == qx) {
|
||||
for (m = 0; m < ps; ++m)
|
||||
newpoints.push(points[i + m]);
|
||||
|
||||
newpoints[l + accumulateOffset] += qy;
|
||||
bottom = qy;
|
||||
|
||||
i += ps;
|
||||
j += otherps;
|
||||
}
|
||||
else if (px > qx) {
|
||||
// we got past point below, might need to
|
||||
// insert interpolated extra point
|
||||
if (withlines && i > 0 && points[i - ps] != null) {
|
||||
intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
|
||||
newpoints.push(qx);
|
||||
newpoints.push(intery + qy);
|
||||
for (m = 2; m < ps; ++m)
|
||||
newpoints.push(points[i + m]);
|
||||
bottom = qy;
|
||||
}
|
||||
|
||||
j += otherps;
|
||||
}
|
||||
else { // px < qx
|
||||
if (fromgap && withlines) {
|
||||
// if we come from a gap, we just skip this point
|
||||
i += ps;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (m = 0; m < ps; ++m)
|
||||
newpoints.push(points[i + m]);
|
||||
|
||||
// we might be able to interpolate a point below,
|
||||
// this can give us a better y
|
||||
if (withlines && j > 0 && otherpoints[j - otherps] != null)
|
||||
bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
|
||||
|
||||
newpoints[l + accumulateOffset] += bottom;
|
||||
|
||||
i += ps;
|
||||
}
|
||||
|
||||
fromgap = false;
|
||||
|
||||
if (l != newpoints.length && withbottom)
|
||||
newpoints[l + 2] += bottom;
|
||||
}
|
||||
|
||||
// maintain the line steps invariant
|
||||
if (withsteps && l != newpoints.length && l > 0
|
||||
&& newpoints[l] != null
|
||||
&& newpoints[l] != newpoints[l - ps]
|
||||
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
|
||||
for (m = 0; m < ps; ++m)
|
||||
newpoints[l + ps + m] = newpoints[l + m];
|
||||
newpoints[l + 1] = newpoints[l - ps + 1];
|
||||
}
|
||||
}
|
||||
|
||||
datapoints.points = newpoints;
|
||||
}
|
||||
|
||||
plot.hooks.processDatapoints.push(stackData);
|
||||
}
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: init,
|
||||
options: options,
|
||||
name: 'stack',
|
||||
version: '1.2'
|
||||
});
|
||||
})(jQuery);
|
|
@ -0,0 +1,36 @@
|
|||
/* Flot plugin for stacking data sets rather than overlyaing them.
|
||||
|
||||
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
The plugin assumes the data is sorted on x (or y if stacking horizontally).
|
||||
For line charts, it is assumed that if a line has an undefined gap (from a
|
||||
null point), then the line above it should have the same gap - insert zeros
|
||||
instead of "null" if you want another behaviour. This also holds for the start
|
||||
and end of the chart. Note that stacking a mix of positive and negative values
|
||||
in most instances doesn't make sense (so it looks weird).
|
||||
|
||||
Two or more series are stacked when their "stack" attribute is set to the same
|
||||
key (which can be any number or string or just "true"). To specify the default
|
||||
stack, you can set the stack option like this:
|
||||
|
||||
series: {
|
||||
stack: null/false, true, or a key (number/string)
|
||||
}
|
||||
|
||||
You can also specify it for a single series, like this:
|
||||
|
||||
$.plot( $("#placeholder"), [{
|
||||
data: [ ... ],
|
||||
stack: true
|
||||
}])
|
||||
|
||||
The stacking order is determined by the order of the data series in the array
|
||||
(later series end up on top of the previous).
|
||||
|
||||
Internally, the plugin modifies the datapoints in each series, adding an
|
||||
offset to the y value. For line series, extra data points are inserted through
|
||||
interpolation. If there's a second y value, it's also adjusted (e.g for bar
|
||||
charts or filled areas).
|
||||
|
||||
*/(function(e){function n(e){function t(e,t){var n=null;for(var r=0;r<t.length;++r){if(e==t[r])break;t[r].stack==e.stack&&(n=t[r])}return n}function n(e,n,r){if(n.stack==null||n.stack===!1)return;var i=t(n,e.getData());if(!i)return;var s=r.pointsize,o=r.points,u=i.datapoints.pointsize,a=i.datapoints.points,f=[],l,c,h,p,d,v,m=n.lines.show,g=n.bars.horizontal,y=s>2&&(g?r.format[2].x:r.format[2].y),b=m&&n.lines.steps,w=!0,E=g?1:0,S=g?0:1,x=0,T=0,N,C;for(;;){if(x>=o.length)break;N=f.length;if(o[x]==null){for(C=0;C<s;++C)f.push(o[x+C]);x+=s}else if(T>=a.length){if(!m)for(C=0;C<s;++C)f.push(o[x+C]);x+=s}else if(a[T]==null){for(C=0;C<s;++C)f.push(null);w=!0;T+=u}else{l=o[x+E];c=o[x+S];p=a[T+E];d=a[T+S];v=0;if(l==p){for(C=0;C<s;++C)f.push(o[x+C]);f[N+S]+=d;v=d;x+=s;T+=u}else if(l>p){if(m&&x>0&&o[x-s]!=null){h=c+(o[x-s+S]-c)*(p-l)/(o[x-s+E]-l);f.push(p);f.push(h+d);for(C=2;C<s;++C)f.push(o[x+C]);v=d}T+=u}else{if(w&&m){x+=s;continue}for(C=0;C<s;++C)f.push(o[x+C]);m&&T>0&&a[T-u]!=null&&(v=d+(a[T-u+S]-d)*(l-p)/(a[T-u+E]-p));f[N+S]+=v;x+=s}w=!1;N!=f.length&&y&&(f[N+2]+=v)}if(b&&N!=f.length&&N>0&&f[N]!=null&&f[N]!=f[N-s]&&f[N+1]!=f[N-s+1]){for(C=0;C<s;++C)f[N+s+C]=f[N+C];f[N+1]=f[N-s+1]}}r.points=f}e.hooks.processDatapoints.push(n)}var t={series:{stack:null}};e.plot.plugins.push({init:n,options:t,name:"stack",version:"1.2"})})(jQuery);
|
|
@ -7,18 +7,20 @@ jQuery(document).ready(function($) {
|
|||
}).appendTo("body").fadeIn(200);
|
||||
}
|
||||
|
||||
var previousPoint = null;
|
||||
var prev_data_index = null;
|
||||
var prev_series_index = null;
|
||||
|
||||
jQuery(".chart-placeholder").bind( "plothover", function (event, pos, item) {
|
||||
if (item) {
|
||||
if (previousPoint != item.dataIndex) {
|
||||
previousPoint = item.dataIndex;
|
||||
if ( prev_data_index != item.dataIndex || prev_series_index != item.seriesIndex ) {
|
||||
prev_data_index = item.dataIndex;
|
||||
prev_series_index = item.seriesIndex;
|
||||
|
||||
jQuery( ".chart-tooltip" ).remove();
|
||||
|
||||
if ( item.series.points.show || item.series.enable_tooltip ) {
|
||||
|
||||
var y = item.datapoint[1];
|
||||
var y = item.series.data[item.dataIndex][1];
|
||||
|
||||
tooltip_content = '';
|
||||
|
||||
|
@ -28,14 +30,27 @@ jQuery(document).ready(function($) {
|
|||
if ( item.series.prepend_tooltip )
|
||||
tooltip_content = tooltip_content + item.series.prepend_tooltip;
|
||||
|
||||
showTooltip( item.pageX, item.pageY, tooltip_content + y );
|
||||
tooltip_content = tooltip_content + y;
|
||||
|
||||
if ( item.series.append_tooltip )
|
||||
tooltip_content = tooltip_content + item.series.append_tooltip;
|
||||
|
||||
if ( item.series.pie.show ) {
|
||||
|
||||
showTooltip( pos.pageX, pos.pageY, tooltip_content );
|
||||
|
||||
} else {
|
||||
|
||||
showTooltip( item.pageX, item.pageY, tooltip_content );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
jQuery(".chart-tooltip").remove();
|
||||
previousPoint = null;
|
||||
prev_data_index = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(document).ready(function(e){function t(e,t,n){jQuery('<div class="chart-tooltip">'+n+"</div>").css({top:t-16,left:e+20}).appendTo("body").fadeIn(200)}var n=null;jQuery(".chart-placeholder").bind("plothover",function(e,r,i){if(i){if(n!=i.dataIndex){n=i.dataIndex;jQuery(".chart-tooltip").remove();if(i.series.points.show||i.series.enable_tooltip){var s=i.datapoint[1];tooltip_content="";i.series.prepend_label&&(tooltip_content=tooltip_content+i.series.label+": ");i.series.prepend_tooltip&&(tooltip_content+=i.series.prepend_tooltip);t(i.pageX,i.pageY,tooltip_content+s)}}}else{jQuery(".chart-tooltip").remove();n=null}});e(".wc_sparkline.bars").each(function(){var t=e(this).data("sparkline"),n={grid:{show:!1}},r=[{data:t,color:e(this).data("color"),bars:{fillColor:e(this).data("color"),fill:!0,show:!0,lineWidth:1,barWidth:e(this).data("barwidth"),align:"center"},shadowSize:0}],i=e.plot(e(this),r,n)});e(".wc_sparkline.lines").each(function(){var t=e(this).data("sparkline"),n={grid:{show:!1}},r=[{data:t,color:e(this).data("color"),lines:{fill:!1,show:!0,lineWidth:1,align:"center"},shadowSize:0}],i=e.plot(e(this),r,n)});var r=jQuery(".range_datepicker").datepicker({defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,maxDate:"+0D",showButtonPanel:!0,showOn:"focus",buttonImageOnly:!0,onSelect:function(e){var t=jQuery(this).is(".from")?"minDate":"maxDate",n=jQuery(this).data("datepicker"),i=jQuery.datepicker.parseDate(n.settings.dateFormat||jQuery.datepicker._defaults.dateFormat,e,n.settings);r.not(this).datepicker("option",t,i)}})});
|
||||
jQuery(document).ready(function(e){function t(e,t,n){jQuery('<div class="chart-tooltip">'+n+"</div>").css({top:t-16,left:e+20}).appendTo("body").fadeIn(200)}var n=null,r=null;jQuery(".chart-placeholder").bind("plothover",function(e,i,s){if(s){if(n!=s.dataIndex||r!=s.seriesIndex){n=s.dataIndex;r=s.seriesIndex;jQuery(".chart-tooltip").remove();if(s.series.points.show||s.series.enable_tooltip){var o=s.series.data[s.dataIndex][1];tooltip_content="";s.series.prepend_label&&(tooltip_content=tooltip_content+s.series.label+": ");s.series.prepend_tooltip&&(tooltip_content+=s.series.prepend_tooltip);tooltip_content+=o;s.series.append_tooltip&&(tooltip_content+=s.series.append_tooltip);s.series.pie.show?t(i.pageX,i.pageY,tooltip_content):t(s.pageX,s.pageY,tooltip_content)}}}else{jQuery(".chart-tooltip").remove();n=null}});e(".wc_sparkline.bars").each(function(){var t=e(this).data("sparkline"),n={grid:{show:!1}},r=[{data:t,color:e(this).data("color"),bars:{fillColor:e(this).data("color"),fill:!0,show:!0,lineWidth:1,barWidth:e(this).data("barwidth"),align:"center"},shadowSize:0}],i=e.plot(e(this),r,n)});e(".wc_sparkline.lines").each(function(){var t=e(this).data("sparkline"),n={grid:{show:!1}},r=[{data:t,color:e(this).data("color"),lines:{fill:!1,show:!0,lineWidth:1,align:"center"},shadowSize:0}],i=e.plot(e(this),r,n)});var i=jQuery(".range_datepicker").datepicker({defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,maxDate:"+0D",showButtonPanel:!0,showOn:"focus",buttonImageOnly:!0,onSelect:function(e){var t=jQuery(this).is(".from")?"minDate":"maxDate",n=jQuery(this).data("datepicker"),r=jQuery.datepicker.parseDate(n.settings.dateFormat||jQuery.datepicker._defaults.dateFormat,e,n.settings);i.not(this).datepicker("option",t,r)}})});
|
Loading…
Reference in New Issue