From 31ab0f1ad48b697caf95317f0e626a7d8204d024 Mon Sep 17 00:00:00 2001 From: mattf Date: Sun, 31 Jul 2016 14:19:56 +0000 Subject: [PATCH] Added and tested ChartJS features for more aesthetically appealing graphs to many reports git-svn-id: svn://192.168.202.10@2568 3d104415-ff17-0410-8863-d5cf3c621b8a --- agc_2-X/trunk/UPGRADE | 2 + .../www/vicidial/AST_CLOSER_service_level.php | 257 +- .../trunk/www/vicidial/AST_CLOSERstats.php | 848 +- .../trunk/www/vicidial/AST_CLOSERstats_v2.php | 851 +- .../www/vicidial/AST_CLOSERsummary_hourly.php | 285 +- agc_2-X/trunk/www/vicidial/AST_DIDstats.php | 300 +- agc_2-X/trunk/www/vicidial/AST_IVRstats.php | 141 +- .../www/vicidial/AST_LISTS_campaign_stats.php | 449 +- .../www/vicidial/AST_LISTS_pass_report.php | 617 +- .../vicidial/AST_OUTBOUNDsummary_interval.php | 297 +- agc_2-X/trunk/www/vicidial/AST_VDADstats.php | 596 +- .../www/vicidial/AST_agent_days_detail.php | 144 +- .../vicidial/AST_agent_performance_detail.php | 312 +- .../www/vicidial/AST_agent_status_detail.php | 142 +- .../www/vicidial/AST_agent_time_detail.php | 232 +- .../vicidial/AST_agent_timeclock_detail.php | 133 +- .../AST_campaign_status_list_report.php | 117 +- .../www/vicidial/AST_inbound_daily_report.php | 588 +- .../AST_performance_comparison_report.php | 149 +- .../vicidial/AST_team_performance_detail.php | 389 +- agc_2-X/trunk/www/vicidial/chart/Chart.js | 10243 ++++++++++++++++ agc_2-X/trunk/www/vicidial/chart_button.php | 54 + agc_2-X/trunk/www/vicidial/fcstats.php | 243 +- .../www/vicidial/graph_color_schemas.inc | 101 + agc_2-X/trunk/www/vicidial/graphcanvas.inc | 93 + .../trunk/www/vicidial/options-example.php | 4 + .../trunk/www/vicidial/timeclock_report.php | 108 +- .../www/vicidial/vicidial_chart_functions.js | 81 + 28 files changed, 15234 insertions(+), 2542 deletions(-) create mode 100644 agc_2-X/trunk/www/vicidial/chart/Chart.js create mode 100644 agc_2-X/trunk/www/vicidial/chart_button.php create mode 100644 agc_2-X/trunk/www/vicidial/graph_color_schemas.inc create mode 100644 agc_2-X/trunk/www/vicidial/graphcanvas.inc create mode 100644 agc_2-X/trunk/www/vicidial/vicidial_chart_functions.js diff --git a/agc_2-X/trunk/UPGRADE b/agc_2-X/trunk/UPGRADE index ef420172..bc265bed 100644 --- a/agc_2-X/trunk/UPGRADE +++ b/agc_2-X/trunk/UPGRADE @@ -274,6 +274,8 @@ OTHER CHANGES: definitions, removed san-serif fonts, changed loading/login/logout screens, logging of browser width/height. +74. Changed HTML Reports to use dynamic charting Javascript elements + diff --git a/agc_2-X/trunk/www/vicidial/AST_CLOSER_service_level.php b/agc_2-X/trunk/www/vicidial/AST_CLOSER_service_level.php index 588b5fc9..023cbec0 100644 --- a/agc_2-X/trunk/www/vicidial/AST_CLOSER_service_level.php +++ b/agc_2-X/trunk/www/vicidial/AST_CLOSER_service_level.php @@ -32,6 +32,7 @@ # 150516-1258 - Fixed Javascript element problem, Issue #857 # 151125-1627 - Added search archive option # 160227-1153 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -294,6 +295,8 @@ while ($i < $groups_to_print) $NWB = "   \"HELP\""; +$JS_text.="\n"; $HEADER.="\n"; $HEADER.="\n"; +require("chart_button.php"); +$HEADER.="\n"; +$HEADER.="\n"; + $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; @@ -735,20 +742,6 @@ $max_calls=1; $max_totalcalltime=1; $max_avgcalltime=1; -$GRAPH="

"; -$GRAPH.=""; -$GRAPH.="
"._QXZ("DROPS").""._QXZ("DROP")." %"._QXZ("AVG DROP(s)").""._QXZ("HOLD").""._QXZ("HOLD")." %"._QXZ("AVG HOLD(s)")." HOLD"._QXZ("AVG HOLD(s) TOTAL").""._QXZ("CALLS").""._QXZ("TOTAL CALLTIME MIN:SEC").""._QXZ("AVG CALLTIME SECONDS")."

 


"; -$graph_header=""; -$DROPS_graph=$graph_header.""; -$DROPPCT_graph=$graph_header.""; -$AVGDROPS_graph=$graph_header.""; -$HOLD_graph=$graph_header.""; -$HOLDPCT_graph=$graph_header.""; -$AVGHOLDS_graph=$graph_header.""; -$AVGHOLDSTOTAL_graph=$graph_header.""; -$CALLS_graph=$graph_header.""; -$TOTALCALLTIME_graph=$graph_header.""; -$AVGCALLTIME_graph=$graph_header.""; $d=0; while ($d < $DURATIONday) { @@ -852,9 +845,6 @@ $ASCII_text.="| "._QXZ("TOTALS",41,"r")." | $FtotDROPS | $FtotDROPSpct%|$FtotDRO $ASCII_text.="+-------------------------------------------+--------+--------+--------+--------+--------+--------+--------+--------+----------+--------+\n"; $CSV_text.="\"TOTALS\",\"$FtotDROPS\",\"$FtotDROPSpct%\",\"$FtotDROPSavg\",\"$FtotQUEUE\",\"$FtotQUEUEpct%\",\"$FtotQUEUEavg\",\"$FtotQUEUEtot\",\"$FtotCALLS\",\"$totTIME_MS\",\"$FtotCALLSavg\"\n"; - - for ($d=0; $d"; $DROPPCT_graph.=" "; $AVGDROPS_graph.=" "; @@ -865,42 +855,86 @@ $CSV_text.="\"TOTALS\",\"$FtotDROPS\",\"$FtotDROPSpct%\",\"$FtotDROPSavg\",\"$Ft $CALLS_graph.=" "; $TOTALCALLTIME_graph.=" "; $AVGCALLTIME_graph.=" "; + + $graph_id++; + $graph_array=array("ACSL_DROPSdata|1|DROPS|integer|", "ACSL_DROPPCTdata|2|DROP PCT|percent|", "ACSL_AVGDROPSdata|3|AVG DROPS|decimal|", "ACSL_HOLDSdata|4|HOLDS|integer|", "ACSL_HOLDPCTdata|5|HOLD PCT|percent|", "ACSL_AVGHOLDSdata|6|AVG HOLDS|decimal|", "ACSL_AVGHOLDSTOTALdata|7|AVG HOLDS TOTAL|decimal|", "ACSL_CALLSdata|8|CALLS|integer|", "ACSL_TOTALCALLTIMEdata|9|TOTAL CALL TIME|time|", "ACSL_AVGCALLTIMEdata|11|AVG CALL TIME|integer|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $DROPS_graph.="
"._QXZ("INBOUND SERVICE LEVEL REPORT")."
"._QXZ("STATUS").""._QXZ("DROPS")."
"._QXZ("DROP")." %
"._QXZ("AVG DROP(s)")."
"._QXZ("HOLD")."
"._QXZ("HOLD")." %
"._QXZ("AVG HOLD(s) HOLD")."
"._QXZ("AVG HOLD(s) TOTAL")."
"._QXZ("CALLS")."
"._QXZ("TOTAL CALLTIME MIN:SEC")."
"._QXZ("AVG CALLTIME SECONDS")."
".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".$graph_stats[$d][2]."%
".$graph_stats[$d][0]."".$graph_stats[$d][3]."
".$graph_stats[$d][0]."".$graph_stats[$d][8]."
".$graph_stats[$d][0]."".$graph_stats[$d][10]."
".$graph_stats[$d][0]."".$graph_stats[$d][11]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($FtotDROPS)."
"; - $DROPPCT_graph.=""._QXZ("TOTAL").":".trim($FtotDROPSpct)."%"; - $AVGDROPS_graph.=""._QXZ("TOTAL").":".trim($FtotDROPSavg).""; - $HOLD_graph.=""._QXZ("TOTAL").":".trim($FtotQUEUE).""; - $HOLDPCT_graph.=""._QXZ("TOTAL").":".trim($FtotQUEUEpct)."%"; - $AVGHOLDS_graph.=""._QXZ("TOTAL").":".trim($FtotQUEUEavg).""; - $AVGHOLDSTOTAL_graph.=""._QXZ("TOTAL").":".trim($FtotQUEUEtot).""; - $CALLS_graph.=""._QXZ("TOTAL").":".trim($FtotCALLS).""; - $TOTALCALLTIME_graph.=""._QXZ("TOTAL").":".trim($totTIME_MS).""; - $AVGCALLTIME_graph.=""._QXZ("TOTAL").":".trim($FtotCALLSavg).""; - $JS_text="\n"; + + if ($report_display_type=="HTML") { - $MAIN.=$GRAPH; + $MAIN.=$GRAPH_text; } else { @@ -1356,9 +1459,9 @@ else { echo "$HEADER"; - echo $JS_text; require("admin_header.php"); echo "$MAIN"; + echo $JS_text; } } diff --git a/agc_2-X/trunk/www/vicidial/AST_CLOSERstats.php b/agc_2-X/trunk/www/vicidial/AST_CLOSERstats.php index c345340b..7840ee2a 100644 --- a/agc_2-X/trunk/www/vicidial/AST_CLOSERstats.php +++ b/agc_2-X/trunk/www/vicidial/AST_CLOSERstats.php @@ -52,6 +52,7 @@ # 151124-1236 - Changed bottom chart to pull all time segments # 151125-1633 - Added search archive option # 160227-1129 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -416,9 +417,14 @@ $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; +require("chart_button.php"); +$HEADER.="\n"; +$HEADER.="\n"; $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; +$JS_text=""; + + $GRAPH_text=""; + ######### + $graph_array=array("ACS_QUEUEseconds|||integer|"); + $graph_id++; + $default_graph="line"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title=_QXZ("QUEUE SECONDS"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas."
";
 	$MAIN.=$GRAPH_text;
 	}
 else 
@@ -1314,10 +1399,7 @@ if ($report_display_type=="HTML") {
 		}
 	}
 	$rslt=mysql_to_mysqli($stmt, $link);
-	
-	$GRAPH_text="
\n"; - $GRAPH_text.=""; + + $GRAPH_text=""; + ######### + $graph_array=array("ACS_DROPTIMEBREAKDOWNseconds|||integer|"); + $graph_id++; + $default_graph="line"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title="DROP TIME BREAKDOWN IN SECONDS"; + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas."
";
+
 	$MAIN.=$GRAPH_text;
 	}
 else
@@ -1604,10 +1769,7 @@ if ($report_display_type=="HTML") {
 		}
 	}
 	$rslt=mysql_to_mysqli($stmt, $link);
-	
-	$GRAPH_text="
\n"; - $GRAPH_text.=""; + + $GRAPH_text=""; + ######### + $graph_array=array("ACS_CATBdata|||integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title="CALL ANSWERED TIME BREAKDOWN"; + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas; + $MAIN.=$GRAPH_text; } else @@ -1684,35 +1929,97 @@ $CSV_text3.="\""._QXZ("TOTAL").":\",\"$TOTALcalls\"\n"; if ($report_display_type=="HTML") { - $ct_ary=array(); + $graph_stats=array(); $rslt=mysql_to_mysqli($stmt, $link); $high_ct=0; $i=0; while ($row=mysqli_fetch_row($rslt)) { if ($row[0]>$high_ct) {$high_ct=$row[0];} - $ct_ary[$i][0]=$row[0]; - $ct_ary[$i][1]=$row[1]; + $graph_stats[$i][0]=$row[0]; + $graph_stats[$i][1]=$row[1]; $i++; } - $GRAPH_text="
\n"; - $GRAPH_text.="\n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - for ($i=0; $i".$ct_ary[$i][1]."\n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; + + $GRAPH_text=""; + ######### + $graph_array=array("ACS_HANGUPREASONdata||HANGUP REASON STATS|integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.="
$rpt_type_verbiage "._QXZ("HANGUP REASON STATS")."
"._QXZ("REASON")." $rpt_type_verbiages
\"\"".$ct_ary[$i][0]."
"._QXZ("TOTAL").": $current_graph_total
TOTAL ".$rpt_type_verbiage.":".trim($TOTALcalls)."
\n"; - $GRAPH_text.="
\n";
+
+	$graph_count=count($graph_array);
+	$graph_title=_QXZ("HANGUP REASON STATS");
+	include("graphcanvas.inc");
+	$GRAPH_text.=$graphCanvas;
+
 	$MAIN.=$GRAPH_text;
 	}
 else
@@ -1731,10 +2038,6 @@ $ASCII_text.="+--------+----------------------+----------------------+----------
 $ASCII_text.="| "._QXZ("STATUS",6)." | "._QXZ("DESCRIPTION",20)." | "._QXZ("CATEGORY",20)." | $rpt_type_verbiages     | "._QXZ("TOTAL TIME",10)." | "._QXZ("AVG TIME",8)." |$rpt_type_verbiages/"._QXZ("HOUR",4)."|\n";
 $ASCII_text.="+--------+----------------------+----------------------+------------+------------+----------+-----------+\n";
 
-$GRAPH="

"; -$GRAPH.=""; -$GRAPH.="
"._QXZ("CALLS").""._QXZ("TOTAL TIME").""._QXZ("AVG TIME").""._QXZ("CALLS/HR")."

 


"; - $CSV_text4.="\n\"$rpt_type_verbiage "._QXZ("STATUS STATS")."\"\n"; $CSV_text4.="\""._QXZ("STATUS")."\",\""._QXZ("DESCRIPTION")."\",\""._QXZ("CATEGORY")."\",\"$rpt_type_verbiages\",\""._QXZ("TOTAL TIME")."\",\""._QXZ("AVG TIME")."\",\"$rpt_type_verbiages/HOUR\"\n"; @@ -1756,11 +2059,6 @@ $max_calls=1; $max_total_time=1; $max_avg_time=1; $max_callshr=1; -$graph_header=""; -$CALLS_graph=$graph_header.""; -$TOTALTIME_graph=$graph_header.""; -$AVGTIME_graph=$graph_header.""; -$CALLSHOUR_graph=$graph_header.""; ########################### while ($i < $statuses_to_print) @@ -1851,45 +2149,95 @@ $ASCII_text.="| "._QXZ("TOTAL:",52)." | $TOTALcalls | $TOTALhours | $TOTALavg | $ASCII_text.="+------------------------------------------------------+------------+------------+----------+-----------+\n"; ####### - $JS_onload="onload = function() {\n"; - $JS_onload.="\tDrawCSSGraph('CALLS', '1');\n"; - $JS_onload.="\tDrawGraph('CALLS', '1');\n"; - for ($d=0; $d"; - $TOTALTIME_graph.=" "; - $AVGTIME_graph.=" "; - $CALLSHOUR_graph.=" "; + $GRAPH_text=""; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("ACS_CSSCALLSdata|1|CALLS|integer|", "ACS_CSSTOTALTIMEdata|2|TOTAL TIME|time|", "ACS_CSSAVGTIMEdata|3|AVERAGE TIME|time|", "ACS_CSSCALLSHRdata|4|CALLS/HR|decimal|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $CALLS_graph.="
"._QXZ("CALL STATUS STATS")."
"._QXZ("STATUS").""._QXZ("CALLS")."
"._QXZ("TOTAL TIME")."
"._QXZ("AVG TIME")."
"._QXZ("CALLS/HR")."
".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][2], 'H')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][3], 'H')."
".$graph_stats[$d][0]."".$graph_stats[$d][4]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTALcalls)."
"; - $TOTALTIME_graph.=""._QXZ("TOTAL").":".trim($TOTALhours).""; - $AVGTIME_graph.=""._QXZ("TOTAL").":".trim($TOTALavg).""; - $CALLSHOUR_graph.=""._QXZ("TOTAL").":".trim($TOTALrate).""; - $JS_text.="\n"; + + $graph_count=count($graph_array); + $graph_title=_QXZ("CALL STATUS STATS"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas."
";
+
 ########
 
 
 $CSV_text4.="\""._QXZ("TOTAL").":\",\"\",\"\",\"$TOTALcalls\",\"$TOTALhours\",\"$TOTALavg\",\"$TOTALrate\"\n";
 if ($report_display_type=="HTML")
 	{
-	$MAIN.=$GRAPH;
+	$MAIN.=$GRAPH_text;
 	}
 else
 	{
@@ -1937,7 +2285,7 @@ $CSV_text5.="\""._QXZ("TOTAL")."\",\"$TOTCATcalls\"\n";
 
 if ($report_display_type=="HTML") 
 	{
-	$ct_ary=array();
+	$graph_stats=array();
 	$r=0; $i=0;
 	$high_ct=0;
 	while ($r < $statcats_to_print)
@@ -1945,34 +2293,94 @@ if ($report_display_type=="HTML")
 	if ($vsc_id[$r] != 'UNDEFINED')
 		{
 		if ($vsc_count[$r]>$high_ct) {$high_ct=$vsc_count[$r];}
-		$ct_ary[$i][0]=$vsc_count[$r];
-		$ct_ary[$i][1]=$vsc_id[$r]."
".$vsc_name[$r]; + $graph_stats[$i][0]=$vsc_count[$r]; + $graph_stats[$i][1]=$vsc_id[$r]." - ".$vsc_name[$r]; $i++; } $r++; } - $GRAPH_text="
\n"; - $GRAPH_text.="\n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - for ($i=0; $i".$ct_ary[$i][1]."\n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; + $GRAPH_text=""; + ######### + $graph_array=array("ACS_CSCSdata||CUSTOM STATUS CATEGORY STATS|integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.="
"._QXZ("CUSTOM STATUS CATEGORY STATS")."
"._QXZ("CATEGORY")." "._QXZ("CALLS")."
\"\"".$ct_ary[$i][0]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTCATcalls)."
\n"; - $GRAPH_text.="
\n";
+
+	$graph_count=count($graph_array);
+	include("graphcanvas.inc");
+	$GRAPH_text.=$graphCanvas."
";
+
 	$MAIN.=$GRAPH_text;
 	}
 else 
@@ -2092,27 +2500,99 @@ if ($report_display_type=="HTML")
 	}
 	$rslt=mysql_to_mysqli($stmt, $link);
 	
-	$GRAPH_text="
\n"; - $GRAPH_text.=""; + + $graph_count=count($graph_array); + $graph_title=_QXZ("DID Summary"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas."
";
+
 	$MAIN.=$GRAPH_text;
 	}
 else
@@ -2142,13 +2622,6 @@ $max_calls=1;
 $max_timehms=1;
 $max_average=1;
 $graph_stats=array();
-$GRAPH="

"; -$GRAPH.=""; -$GRAPH.="
"._QXZ("CALLS").""._QXZ("TIME H:M:S").""._QXZ("AVERAGE")."

 


"; -$graph_header=""; -$CALLS_graph=$graph_header.""; -$TIMEHMS_graph=$graph_header.""; -$AVERAGE_graph=$graph_header.""; $stmt="select ".$vicidial_closer_log_table.".user,full_name,count(*),sum(length_in_sec),avg(length_in_sec) from ".$vicidial_closer_log_table.",vicidial_users where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' and campaign_id IN($group_SQL) and ".$vicidial_closer_log_table.".user is not null and length_in_sec is not null and ".$vicidial_closer_log_table.".user=vicidial_users.user group by ".$vicidial_closer_log_table.".user;"; if ($DID=='Y') @@ -2215,36 +2688,87 @@ $ASCII_text.="+--------------------------+------------+------------+--------+\n" $ASCII_text.="| "._QXZ("TOTAL Agents:",13)." $TOTagents | $TOTcalls | $TOTtime | $TOTavg |\n"; $ASCII_text.="+--------------------------+------------+------------+--------+\n"; -for ($d=0; $d"; - $TIMEHMS_graph.=" "; - $AVERAGE_graph.=" "; +$GRAPH_text=""; +# USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name +$multigraph_text=""; +$graph_id++; +$graph_array=array("ACS_AGENTSTATSCALLSdata|1|AGENT STATS - CALLS|integer|", "ACS_AGENTSTATSTIMEdata|2|AGENT STATS - TIME H:M:S|time|", "ACS_AGENTSTATSAVERAGEdata|3|AGENT STATS - AVERAGE TIME|time|"); +$default_graph="bar"; # Graph that is initally displayed when page loads +include("graph_color_schemas.inc"); + +$graph_totals_array=array(); +$graph_totals_rawdata=array(); +for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } -$CALLS_graph.="
"._QXZ("AGENT STATS")."
"._QXZ("AGENT")."$rpt_type_verbiages
"._QXZ("TIME H:M:S")."
"._QXZ("AVERAGE")."
".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][2], 'H')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][3], 'H')."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTALcalls)."
"; -$TIMEHMS_graph.=""._QXZ("TOTAL").":".trim($TOTtime).""; -$AVERAGE_graph.=""._QXZ("TOTAL").":".trim($TOTavg).""; -$JS_text.="\n"; -$GRAPH_text=$GRAPH; if ($report_display_type=="HTML") { @@ -2647,9 +3171,13 @@ if ($file_download>0) { } else { echo $HEADER; - echo $JS_text; require("admin_header.php"); echo $MAIN; + $JS_text.="\n"; + if ($report_display_type=="HTML") + { + echo $JS_text; + } } } diff --git a/agc_2-X/trunk/www/vicidial/AST_CLOSERstats_v2.php b/agc_2-X/trunk/www/vicidial/AST_CLOSERstats_v2.php index 98717508..8589bb77 100644 --- a/agc_2-X/trunk/www/vicidial/AST_CLOSERstats_v2.php +++ b/agc_2-X/trunk/www/vicidial/AST_CLOSERstats_v2.php @@ -55,6 +55,7 @@ # 151218-0651 - Added User Group Call Times restrictions to select list # 151219-1702 - Some text changes for more efficient dynamic language function # 160227-1101 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -100,7 +101,6 @@ $db_source = 'M'; if ($DID=='Y') {$report_name = 'Inbound Report by DID';} -# $test_table_name="vicidial_closer_log"; ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### @@ -418,16 +418,20 @@ $HEADER.=" .purple {color: white; background-color: purple}\n"; $HEADER.="-->\n"; $HEADER.=" \n"; - $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; +require("chart_button.php"); +$HEADER.="\n"; +$HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; +$JS_text=""; + + $GRAPH_text=""; + ######### + $graph_array=array("ACS_QUEUEseconds|||integer|"); + $graph_id++; + $default_graph="line"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title=_QXZ("QUEUE SECONDS"); + include("graphcanvas.inc"); + $GRAPH_text=$graphCanvas; + $MAIN.=$GRAPH_text; } else @@ -1661,10 +1744,6 @@ if ($report_display_type=="HTML") { } } $rslt=mysql_to_mysqli($stmt, $link); - - $GRAPH_text="
\n"; - $GRAPH_text.=""; + + $GRAPH_text=""; + ######### + $graph_array=array("ACS_DROPTIMEBREAKDOWNseconds|||integer|"); + $graph_id++; + $default_graph="line"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title=_QXZ("DROP TIME BREAKDOWN IN SECONDS"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas."
";
+
 	$MAIN.=$GRAPH_text;
 	}
 else
@@ -1951,10 +2113,7 @@ if ($report_display_type=="HTML") {
 		}
 	}
 	$rslt=mysql_to_mysqli($stmt, $link);
-	
-	$GRAPH_text="
\n"; - $GRAPH_text.=""; + + $GRAPH_text=""; + ######### + $graph_array=array("ACS_CATBdata|||integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title=_QXZ("CALL ANSWERED TIME BREAKDOWN"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas; + $MAIN.=$GRAPH_text; } else @@ -2031,35 +2273,97 @@ $CSV_text3.="\""._QXZ("TOTAL").":\",\"$TOTALcalls\"\n"; if ($report_display_type=="HTML") { - $ct_ary=array(); + $graph_stats=array(); $rslt=mysql_to_mysqli($stmt, $link); $high_ct=0; $i=0; while ($row=mysqli_fetch_row($rslt)) { if ($row[0]>$high_ct) {$high_ct=$row[0];} - $ct_ary[$i][0]=$row[0]; - $ct_ary[$i][1]=$row[1]; + $graph_stats[$i][0]=$row[0]; + $graph_stats[$i][1]=$row[1]; $i++; } - $GRAPH_text="
\n"; - $GRAPH_text.="\n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - for ($i=0; $i".$ct_ary[$i][1]."\n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; + + $GRAPH_text=""; + ######### + $graph_array=array("ACS_HANGUPREASONdata||HANGUP REASON STATS|integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.="
$rpt_type_verbiage "._QXZ("HANGUP REASON STATS")."
"._QXZ("REASON")." $rpt_type_verbiages
\"\"".$ct_ary[$i][0]."
"._QXZ("TOTAL").": $current_graph_total
TOTAL ".$rpt_type_verbiage.":".trim($TOTALcalls)."
\n"; - $GRAPH_text.="
\n";
+
+	$graph_count=count($graph_array);
+	$graph_title=_QXZ("HANGUP REASON STATS");
+	include("graphcanvas.inc");
+	$GRAPH_text.=$graphCanvas;
+
 	$MAIN.=$GRAPH_text;
 	}
 else
@@ -2077,11 +2381,6 @@ $ASCII_text.="---------- $rpt_type_verbiage "._QXZ("STATUS STATS",18)." "._QXZ("CALLS").""._QXZ("TOTAL TIME").""._QXZ("AVG TIME").""._QXZ("CALLS/HR")."";
-$GRAPH.="
 


"; - $CSV_text4.="\n\"$rpt_type_verbiage "._QXZ("STATUS STATS")."\"\n"; $CSV_text4.="\""._QXZ("STATUS")."\",\""._QXZ("DESCRIPTION")."\",\""._QXZ("CATEGORY")."\",\"$rpt_type_verbiages\",\""._QXZ("TOTAL TIME")."\",\""._QXZ("AVG TIME")."\",\"$rpt_type_verbiages/HOUR\"\n"; @@ -2103,11 +2402,6 @@ $max_calls=1; $max_total_time=1; $max_avg_time=1; $max_callshr=1; -$graph_header=""; -$CALLS_graph=$graph_header.""; -$TOTALTIME_graph=$graph_header.""; -$AVGTIME_graph=$graph_header.""; -$CALLSHOUR_graph=$graph_header.""; ########################### while ($i < $statuses_to_print) @@ -2198,45 +2492,95 @@ $ASCII_text.="| "._QXZ("TOTAL:",52)." | $TOTALcalls | $TOTALhours | $TOTALavg | $ASCII_text.="+------------------------------------------------------+------------+------------+----------+-----------+\n"; ####### - $JS_onload="onload = function() {\n"; - $JS_onload.="\tDrawCSSGraph('CALLS', '1');\n"; - $JS_onload.="\tDrawGraph('CALLS', '1');\n"; - for ($d=0; $d"; - $TOTALTIME_graph.=" "; - $AVGTIME_graph.=" "; - $CALLSHOUR_graph.=" "; + $GRAPH_text=""; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("ACS_CSSCALLSdata|1|CALLS|integer|", "ACS_CSSTOTALTIMEdata|2|TOTAL TIME|time|", "ACS_CSSAVGTIMEdata|3|AVERAGE TIME|time|", "ACS_CSSCALLSHRdata|4|CALLS/HR|decimal|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $CALLS_graph.="
"._QXZ("CALL STATUS STATS")."
"._QXZ("STATUS").""._QXZ("CALLS")."
"._QXZ("TOTAL TIME")."
"._QXZ("AVG TIME")."
"._QXZ("CALLS/HR")."
".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][2], 'H')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][3], 'H')."
".$graph_stats[$d][0]."".$graph_stats[$d][4]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTALcalls)."
"; - $TOTALTIME_graph.=""._QXZ("TOTAL").":".trim($TOTALhours).""; - $AVGTIME_graph.=""._QXZ("TOTAL").":".trim($TOTALavg).""; - $CALLSHOUR_graph.=""._QXZ("TOTAL").":".trim($TOTALrate).""; - $JS_text.="\n"; + + $graph_count=count($graph_array); + $graph_title=_QXZ("CALL STATUS STATS"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas."
";
+
 ########
 
 
 $CSV_text4.="\""._QXZ("TOTAL").":\",\"\",\"\",\"$TOTALcalls\",\"$TOTALhours\",\"$TOTALavg\",\"$TOTALrate\"\n";
 if ($report_display_type=="HTML")
 	{
-	$MAIN.=$GRAPH;
+	$MAIN.=$GRAPH_text;
 	}
 else
 	{
@@ -2284,7 +2628,7 @@ $CSV_text5.="\""._QXZ("TOTAL")."\",\"$TOTCATcalls\"\n";
 
 if ($report_display_type=="HTML") 
 	{
-	$ct_ary=array();
+	$graph_stats=array();
 	$r=0; $i=0;
 	$high_ct=0;
 	while ($r < $statcats_to_print)
@@ -2292,34 +2636,94 @@ if ($report_display_type=="HTML")
 	if ($vsc_id[$r] != 'UNDEFINED')
 		{
 		if ($vsc_count[$r]>$high_ct) {$high_ct=$vsc_count[$r];}
-		$ct_ary[$i][0]=$vsc_count[$r];
-		$ct_ary[$i][1]=$vsc_id[$r]."
".$vsc_name[$r]; + $graph_stats[$i][0]=$vsc_count[$r]; + $graph_stats[$i][1]=$vsc_id[$r]." - ".$vsc_name[$r]; $i++; } $r++; } - $GRAPH_text="
\n"; - $GRAPH_text.="\n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - for ($i=0; $i".$ct_ary[$i][1]."\n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; + $GRAPH_text=""; + ######### + $graph_array=array("ACS_CSCSdata||CUSTOM STATUS CATEGORY STATS|integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.=" \n"; - $GRAPH_text.="
"._QXZ("CUSTOM STATUS CATEGORY STATS")."
"._QXZ("CATEGORY")." "._QXZ("CALLS")."
\"\"".$ct_ary[$i][0]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTCATcalls)."
\n"; - $GRAPH_text.="
\n";
+
+	$graph_count=count($graph_array);
+	include("graphcanvas.inc");
+	$GRAPH_text.=$graphCanvas."
";
+
 	$MAIN.=$GRAPH_text;
 	}
 else 
@@ -2439,27 +2843,99 @@ if ($report_display_type=="HTML")
 	}
 	$rslt=mysql_to_mysqli($stmt, $link);
 	
-	$GRAPH_text="
\n"; - $GRAPH_text.=""; + + $graph_count=count($graph_array); + $graph_title=_QXZ("DID Summary"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas."
";
+
 	$MAIN.=$GRAPH_text;
 	}
 else
@@ -2489,14 +2965,6 @@ $max_calls=1;
 $max_timehms=1;
 $max_average=1;
 $graph_stats=array();
-$GRAPH="

"; -$GRAPH.=""; -$GRAPH.="
"._QXZ("CALLS").""._QXZ("TIME H:M:S").""._QXZ("AVERAGE")."

 


"; -$graph_header=""; -$CALLS_graph=$graph_header.""; -$TIMEHMS_graph=$graph_header.""; -$AVERAGE_graph=$graph_header.""; - $stmt="select ".$vicidial_closer_log_table.".user,full_name,count(*),sum(length_in_sec),avg(length_in_sec) from ".$vicidial_closer_log_table.",vicidial_users where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' $calldate_call_time_clause and campaign_id IN($group_SQL) and ".$vicidial_closer_log_table.".user is not null and length_in_sec is not null and ".$vicidial_closer_log_table.".user=vicidial_users.user group by ".$vicidial_closer_log_table.".user;"; if ($DID=='Y') { @@ -2562,36 +3030,87 @@ $ASCII_text.="+--------------------------+------------+------------+--------+\n" $ASCII_text.="| "._QXZ("TOTAL Agents:",13)." $TOTagents | $TOTcalls | $TOTtime | $TOTavg |\n"; $ASCII_text.="+--------------------------+------------+------------+--------+\n"; -for ($d=0; $d"; - $TIMEHMS_graph.=" "; - $AVERAGE_graph.=" "; +$GRAPH_text=""; +# USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name +$multigraph_text=""; +$graph_id++; +$graph_array=array("ACS_AGENTSTATSCALLSdata|1|AGENT STATS - CALLS|integer|", "ACS_AGENTSTATSTIMEdata|2|AGENT STATS - TIME H:M:S|time|", "ACS_AGENTSTATSAVERAGEdata|3|AGENT STATS - AVERAGE TIME|time|"); +$default_graph="bar"; # Graph that is initally displayed when page loads +include("graph_color_schemas.inc"); + +$graph_totals_array=array(); +$graph_totals_rawdata=array(); +for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } -$CALLS_graph.="
"._QXZ("AGENT STATS")."
"._QXZ("AGENT")."$rpt_type_verbiages
"._QXZ("TIME H:M:S")."
"._QXZ("AVERAGE")."
".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][2], 'H')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][3], 'H')."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTALcalls)."
"; -$TIMEHMS_graph.=""._QXZ("TOTAL").":".trim($TOTtime).""; -$AVERAGE_graph.=""._QXZ("TOTAL").":".trim($TOTavg).""; -$JS_text.="\n"; -$GRAPH_text=$GRAPH; if ($report_display_type=="HTML") { @@ -2998,9 +3517,13 @@ if ($file_download>0) { } else { echo $HEADER; - echo $JS_text; require("admin_header.php"); echo $MAIN; + $JS_text.="\n"; + if ($report_display_type=="HTML") + { + echo $JS_text; + } } } diff --git a/agc_2-X/trunk/www/vicidial/AST_CLOSERsummary_hourly.php b/agc_2-X/trunk/www/vicidial/AST_CLOSERsummary_hourly.php index 7e81b473..9f4c621a 100644 --- a/agc_2-X/trunk/www/vicidial/AST_CLOSERsummary_hourly.php +++ b/agc_2-X/trunk/www/vicidial/AST_CLOSERsummary_hourly.php @@ -26,6 +26,7 @@ # 150516-1300 - Fixed Javascript element problem, Issue #857 # 151125-1609 - Added search archive option # 160227-1151 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -390,6 +391,9 @@ $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; +require("chart_button.php"); +$HEADER.="\n"; +$HEADER.="\n"; $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; @@ -590,26 +594,6 @@ else $CSV_subreports=""; $graph_stats=array(); - $max_calls=1; - $max_answer=1; - $max_talk=1; - $max_avgtalk=1; - $max_queue=1; - $max_avgqueue=1; - $max_maxqueue=1; - $max_totalabandons=1; - $GRAPH="

"; - $GRAPH.=""; - $GRAPH.="
TOTAL CALLSTOTAL ANSWERTOTAL TALKAVERAGE TALKTOTAL QUEUE TIMEAVERAGE QUEUE TIMEMAXIMUM QUEUE TIMETOTAL ABANDON CALLS

 


"; - $graph_header=""; - $CALLS_graph=$graph_header.""; - $ANSWER_graph=$graph_header.""; - $TALK_graph=$graph_header.""; - $AVGTALK_graph=$graph_header.""; - $QUEUE_graph=$graph_header.""; - $AVGQUEUE_graph=$graph_header.""; - $MAXQUEUE_graph=$graph_header.""; - $TOTALABANDONS_graph=$graph_header.""; $i=0; $TOTcalls_count=0; @@ -806,26 +790,6 @@ else $CSV_subreports.="\"HOUR\",\"TOTAL CALLS\",\"TOTAL ANSWER\",\" TOTAL TALK\",\" AVERAGE TALK\",\" TOTAL QUEUE TIME\",\" AVERAGE QUEUE TIME\",\" MAXIMUM QUEUE TIME\",\" TOTAL ABANDON CALLS\"\n"; $sub_graph_stats=array(); - $sub_max_calls=1; - $sub_max_answer=1; - $sub_max_talk=1; - $sub_max_avgtalk=1; - $sub_max_queue=1; - $sub_max_avgqueue=1; - $sub_max_maxqueue=1; - $sub_max_totalabandons=1; - $sub_GRAPH.="

INBOUND SERVICE LEVEL REPORT
IN-GROUPTOTAL CALLS
TOTAL ANSWER
TOTAL TALK
AVERAGE TALK
TOTAL QUEUE TIME
AVERAGE QUEUE TIME
MAXIMUM QUEUE TIME
TOTAL ABANDON CALLS
"; - $sub_GRAPH.=""; - $sub_GRAPH.="
TOTAL CALLSTOTAL ANSWERTOTAL TALKAVERAGE TALKTOTAL QUEUE TIMEAVERAGE QUEUE TIMEMAXIMUM QUEUE TIMETOTAL ABANDON CALLS

 


"; - $sub_graph_header=""; - $sub_CALLS_graph=$sub_graph_header.""; - $sub_ANSWER_graph=$sub_graph_header.""; - $sub_TALK_graph=$sub_graph_header.""; - $sub_AVGTALK_graph=$sub_graph_header.""; - $sub_QUEUE_graph=$sub_graph_header.""; - $sub_AVGQUEUE_graph=$sub_graph_header.""; - $sub_MAXQUEUE_graph=$sub_graph_header.""; - $sub_TOTALABANDONS_graph=$sub_graph_header.""; $h=0; $q=0; while ($h < 24) @@ -920,46 +884,85 @@ else $hTOTmax_queue_seconds = sprintf("%7s", $hTOTmax_queue_seconds); $hTOTdrop_count = sprintf("%6s", $hTOTdrop_count); + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("ACSH_TOTALCALLS$group[$i]data|1|TOTAL CALLS|integer|", "ACSH_TOTALANSWER$group[$i]data|2|TOTAL ANSWER|integer|", "ACSH_TOTALTALK$group[$i]data|3|TOTAL TALK|time|", "ACSH_AVERAGETALK$group[$i]data|4|AVERAGE TALK|time|", "ACSH_TOTALQUEUE$group[$i]data|5|TOTAL QUEUE TIME|time|", "ACSH_AVERAGEQUEUE$group[$i]data|6|AVERAGE QUEUE TIME|time|", "ACSH_MAXQUEUE$group[$i]data|7|MAXIMUM QUEUE TIME|time|", "ACSH_TOTALABANDON$group[$i]data|8|TOTAL ABANDON CALLS|integer|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); - for ($q=0; $q"; - $sub_ANSWER_graph.=" "; - $sub_TALK_graph.=" "; - $sub_AVGTALK_graph.=" "; - $sub_QUEUE_graph.=" "; - $sub_AVGQUEUE_graph.=" "; - $sub_MAXQUEUE_graph.=" "; - $sub_TOTALABANDONS_graph.=" "; + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $sub_CALLS_graph.="
$group[$i] - $group_name[$i] HOURLY BREAKDOWN
HOURTOTAL CALLS
TOTAL ANSWER
TOTAL TALK
AVERAGE TALK
TOTAL QUEUE TIME
AVERAGE QUEUE TIME
MAXIMUM QUEUE TIME
TOTAL ABANDON CALLS
".$sub_graph_stats[$q][1]."
".$sub_graph_stats[$q][0]."".$sub_graph_stats[$q][2]."
".$sub_graph_stats[$q][0]."".sec_convert($sub_graph_stats[$q][3],'H')."
".$sub_graph_stats[$q][0]."".sec_convert($sub_graph_stats[$q][4],'H')."
".$sub_graph_stats[$q][0]."".sec_convert($sub_graph_stats[$q][5],'H')."
".$sub_graph_stats[$q][0]."".sec_convert($sub_graph_stats[$q][6],'H')."
".$sub_graph_stats[$q][0]."".sec_convert($sub_graph_stats[$q][7],'H')."
".$sub_graph_stats[$q][0]."".$sub_graph_stats[$q][8]."
"._QXZ("TOTAL").": $current_graph_total
TOTAL:".trim($hTOTcalls_count)."
"; - $sub_ANSWER_graph.="TOTAL:".trim($hTOTanswer_count).""; - $sub_TALK_graph.="TOTAL:".trim($hTOTtalk_sec).""; - $sub_AVGTALK_graph.="TOTAL:".trim($hTOTtalk_avg).""; - $sub_QUEUE_graph.="TOTAL:".trim($hTOTqueue_seconds).""; - $sub_AVGQUEUE_graph.="TOTAL:".trim($hTOTqueue_avg).""; - $sub_MAXQUEUE_graph.="TOTAL:".trim($hTOTmax_queue_seconds).""; - $sub_TOTALABANDONS_graph.="TOTAL:".trim($hTOTdrop_count).""; - $JS_onload.="\tDraw".$group[$i]."Graph('CALLS', '1');\n"; - $JS_text.="function Draw".$group[$i]."Graph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$sub_CALLS_graph\";\n"; - $JS_text.=" var ANSWER_graph=\"$sub_ANSWER_graph\";\n"; - $JS_text.=" var TALK_graph=\"$sub_TALK_graph\";\n"; - $JS_text.=" var AVGTALK_graph=\"$sub_AVGTALK_graph\";\n"; - $JS_text.=" var QUEUE_graph=\"$sub_QUEUE_graph\";\n"; - $JS_text.=" var AVGQUEUE_graph=\"$sub_AVGQUEUE_graph\";\n"; - $JS_text.=" var MAXQUEUE_graph=\"$sub_MAXQUEUE_graph\";\n"; - $JS_text.=" var TOTALABANDONS_graph=\"$sub_TOTALABANDONS_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=8; i++) {\n"; - $JS_text.=" var cellID=\"".$group[$i]."_graph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"".$group[$i]."_graph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('".$group[$i]."_stats_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; + + $graph_count=count($graph_array); + $graph_title=" $group[$i] - $group_name[$i]
"._QXZ("INBOUND SERVICE LEVEL REPORT"); + include("graphcanvas.inc"); + $sub_GRAPH.=$graphCanvas; $SUBoutput .= "+------+--------+--------+-----------+---------+-----------+---------+---------+--------+\n"; @@ -977,55 +980,87 @@ else $TOTtalk_avg = MathZDC($TOTtalk_sec, $TOTanswer_count); $TOTqueue_avg = MathZDC($TOTqueue_seconds, $TOTcalls_count); - for ($q=0; $q".$graph_stats[$q][1].""; - $ANSWER_graph.=" ".$graph_stats[$q][0]."".$graph_stats[$q][2].""; - $TALK_graph.=" ".$graph_stats[$q][0]."".sec_convert($graph_stats[$q][3],'H').""; - $AVGTALK_graph.=" ".$graph_stats[$q][0]."".sec_convert($graph_stats[$q][4],'H').""; - $QUEUE_graph.=" ".$graph_stats[$q][0]."".sec_convert($graph_stats[$q][5],'H').""; - $AVGQUEUE_graph.=" ".$graph_stats[$q][0]."".sec_convert($graph_stats[$q][6],'H').""; - $MAXQUEUE_graph.=" ".$graph_stats[$q][0]."".sec_convert($graph_stats[$q][7],'H').""; - $TOTALABANDONS_graph.=" ".$graph_stats[$q][0]."".$graph_stats[$q][8].""; + + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("ACSH_TOTALCALLSdata|1|TOTAL CALLS|integer|", "ACSH_TOTALANSWERdata|2|TOTAL ANSWERS|integer|", "ACSH_TOTALTALKdata|3|TOTAL TALK TIME|time|", "ACSH_AVERAGETALKdata|4|AGV TALK TIME|time|", "ACSH_TOTALQUEUEdata|5|TOTAL QUEUE TIME|time|", "ACSH_AVERAGEQUEUEdata|6|AVERAGE QUEUE TIME|time|", "ACSH_MAXQUEUEdata|7|MAXIMUM QUEUE TIME|time|", "ACSH_TOTALABANDONdata|8|TOTAL ABANDON CALLS|integer|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $gTOTtalk_avg = round(MathZDC($gTOTtalk_sec, $gTOTanswer_count)); - $gTOTqueue_avg = round(MathZDC($gTOTqueue_seconds, $gTOTcalls_count)); + $graph_count=count($graph_array); + $graph_title=_QXZ("INBOUND SERVICE LEVEL REPORT"); + include("graphcanvas.inc"); + $GRAPH.=$graphCanvas; + - $gTOTtalk_sec = sec_convert($gTOTtalk_sec,'H'); - $gTOTtalk_avg = sec_convert($gTOTtalk_avg,'H'); - $gTOTqueue_seconds = sec_convert($gTOTqueue_seconds,'H'); - $gTOTqueue_avg = sec_convert($gTOTqueue_avg,'H'); - $gTOTmax_queue_seconds = sec_convert($gTOTmax_queue_seconds,'H'); - $CALLS_graph.="TOTAL:".trim($gTOTcalls_count).""; - $ANSWER_graph.="TOTAL:".trim($gTOTanswer_count).""; - $TALK_graph.="TOTAL:".trim($gTOTtalk_sec).""; - $AVGTALK_graph.="TOTAL:".trim($gTOTtalk_avg).""; - $QUEUE_graph.="TOTAL:".trim($gTOTqueue_seconds).""; - $AVGQUEUE_graph.="TOTAL:".trim($gTOTqueue_avg).""; - $MAXQUEUE_graph.="TOTAL:".trim($gTOTmax_queue_seconds).""; - $TOTALABANDONS_graph.="TOTAL:".trim($gTOTdrop_count).""; - $JS_onload.="\tDrawGraph('CALLS', '1');\n"; - $JS_text.="function DrawGraph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$CALLS_graph\";\n"; - $JS_text.=" var ANSWER_graph=\"$ANSWER_graph\";\n"; - $JS_text.=" var TALK_graph=\"$TALK_graph\";\n"; - $JS_text.=" var AVGTALK_graph=\"$AVGTALK_graph\";\n"; - $JS_text.=" var QUEUE_graph=\"$QUEUE_graph\";\n"; - $JS_text.=" var AVGQUEUE_graph=\"$AVGQUEUE_graph\";\n"; - $JS_text.=" var MAXQUEUE_graph=\"$MAXQUEUE_graph\";\n"; - $JS_text.=" var TOTALABANDONS_graph=\"$TOTALABANDONS_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=8; i++) {\n"; - $JS_text.=" var cellID=\"multigroup_graph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"multigroup_graph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('multigroup_stats_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $TOTtalk_sec = sec_convert($TOTtalk_sec,'H'); @@ -1123,9 +1158,9 @@ else } echo "$HEADER"; - echo $JS_text; require("admin_header.php"); echo "$MAIN"; + echo $JS_text; # echo "$SUBoutput"; diff --git a/agc_2-X/trunk/www/vicidial/AST_DIDstats.php b/agc_2-X/trunk/www/vicidial/AST_DIDstats.php index 3a157951..dd931279 100644 --- a/agc_2-X/trunk/www/vicidial/AST_DIDstats.php +++ b/agc_2-X/trunk/www/vicidial/AST_DIDstats.php @@ -28,6 +28,7 @@ # 141230-1508 - Added code for on-the-fly language translations display # 151125-1614 - Added search archive option # 160227-1150 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -346,6 +347,9 @@ $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; +require("chart_button.php"); +$HEADER.="\n"; +$HEADER.="\n"; $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; @@ -444,6 +448,7 @@ $MAIN.="\n"; $MAIN.="
";
 
+$JS_text="";
+
 	if ($report_display_type=="HTML")
 		{
-		$MAIN.=$GRAPH_text;
+		$MAIN.=$GRAPH_text.$JS_text;
 		}
 	else
 		{
diff --git a/agc_2-X/trunk/www/vicidial/AST_IVRstats.php b/agc_2-X/trunk/www/vicidial/AST_IVRstats.php
index 57761b7f..5b279432 100644
--- a/agc_2-X/trunk/www/vicidial/AST_IVRstats.php
+++ b/agc_2-X/trunk/www/vicidial/AST_IVRstats.php
@@ -34,6 +34,7 @@
 # 151125-1643 - Added search archive option
 # 151204-0544 - Added code to look for "CALL_MENU" and "XML_PULL" In-Group permissions for those list options
 # 160227-1130 - Uniform form format
+# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs
 #
 
 $startMS = microtime();
@@ -75,8 +76,6 @@ if ($type == 'inbound')
 else
 	{$report_name = 'Outbound IVR Report';}
 $db_source = 'M';
-$JS_text="\n";
 $HEADER.="\n";
 $HEADER.="\n";
-
+require("chart_button.php");
+$HEADER.="\n"; 
+$HEADER.="\n";
 
 $HEADER.="\n";
 $HEADER.=""._QXZ("$report_name")."\n";
@@ -483,6 +484,7 @@ $HEADER.=""._QXZ("$report_name")." $NWB#IVRstats$NWE\n";
 $MAIN.="
"; @@ -818,15 +820,6 @@ else $max_queue_drops_percent=1; $max_ivr_avg=1; $max_total_avg=1; - $GRAPH=""; - $GRAPH.=""; - $GRAPH.="
"._QXZ("IVR CALLS").""._QXZ("QUEUE CALLS").""._QXZ("QUEUE DROP CALLS").""._QXZ("QUEUE DROP PERCENT").""._QXZ("IVR AVG TIME").""._QXZ("TOTAL AVG TIME")."

 


"; - $IVRCALLS_graph=""; - $QUEUECALLS_graph="
"._QXZ("IVR STATS")."
"._QXZ("IVR CALLS").""._QXZ("CALL PATH")."
"; - $QUEUEDROPCALLS_graph="
"._QXZ("IVR STATS")."
"._QXZ("QUEUE CALLS").""._QXZ("CALL PATH")."
"; - $QUEUEDROPPERCENT_graph="
"._QXZ("IVR STATS")."
"._QXZ("QUEUE DROP CALLS").""._QXZ("CALL PATH")."
"; - $IVRAVGTIME_graph="
"._QXZ("IVR STATS")."
"._QXZ("QUEUE DROP PERCENT").""._QXZ("CALL PATH")."
"; - $TOTALAVGTIME_graph="
"._QXZ("IVR STATS")."
"._QXZ("IVR AVG TIME").""._QXZ("CALL PATH")."
"; ########################### $CSV_text.="\"\",\""._QXZ("IVR CALLS")."\",\""._QXZ("QUEUE CALLS")."\",\""._QXZ("QUEUE DROP CALLS")."\",\""._QXZ("QUEUE DROP PERCENT")."\",\""._QXZ("IVR AVG TIME")."\",\""._QXZ("TOTAL AVG TIME")."\",\""._QXZ("CALL PATH")."\"\n"; @@ -925,41 +918,88 @@ else $CSV_text.="\"\",\"$TOTALcalls\",\"$totFLOWtotal\",\"$totFLOWdrop\",\"$totFLOWdropPCT%\",\"$TavgFLOWivr_time\",\"$TavgFLOWtotal_time\"\n"; - for ($d=0; $d".$graph_stats[$d][1].""; - $QUEUECALLS_graph.=" "; - $QUEUEDROPCALLS_graph.=" "; - $QUEUEDROPPERCENT_graph.=" "; - $IVRAVGTIME_graph.=" "; - $TOTALAVGTIME_graph.=" "; - } - $IVRCALLS_graph.="
"._QXZ("IVR STATS")."
"._QXZ("TOTAL AVG TIME").""._QXZ("CALL PATH")."
".$graph_stats[$d][0]."
".$graph_stats[$d][2]."".$graph_stats[$d][0]."
".$graph_stats[$d][3]."".$graph_stats[$d][0]."
".$graph_stats[$d][4]."%".$graph_stats[$d][0]."
".$graph_stats[$d][5]."".$graph_stats[$d][0]."
".$graph_stats[$d][6]."".$graph_stats[$d][0]."
".trim($TOTALcalls).""._QXZ("TOTAL")."
"; - $QUEUECALLS_graph.="
".trim($totFLOWtotal).""._QXZ("TOTAL")."
"; - $QUEUEDROPCALLS_graph.="".trim($totFLOWdrop).""._QXZ("TOTAL").""; - $QUEUEDROPPERCENT_graph.="".trim($totFLOWdropPCT)."%"._QXZ("TOTAL").""; - $IVRAVGTIME_graph.="".trim($TavgFLOWivr_time).""._QXZ("TOTAL").""; - $TOTALAVGTIME_graph.="".trim($TavgFLOWtotal_time).""._QXZ("TOTAL").""; - $JS_onload.="\tDrawGraph('IVRCALLS', '1');\n"; - $JS_text.="function DrawGraph(graph, th_id) {\n"; - $JS_text.=" var IVRCALLS_graph=\"$IVRCALLS_graph\";\n"; - $JS_text.=" var QUEUECALLS_graph=\"$QUEUECALLS_graph\";\n"; - $JS_text.=" var QUEUEDROPCALLS_graph=\"$QUEUEDROPCALLS_graph\";\n"; - $JS_text.=" var QUEUEDROPPERCENT_graph=\"$QUEUEDROPPERCENT_graph\";\n"; - $JS_text.=" var IVRAVGTIME_graph=\"$IVRAVGTIME_graph\";\n"; - $JS_text.=" var TOTALAVGTIME_graph=\"$TOTALAVGTIME_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=6; i++) {\n"; - $JS_text.=" var cellID=\"ivrgraph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"ivrgraph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('ivr_stats_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $GRAPH_text.=$GRAPH; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("IVRSTATS_IVRCALLSdata|1|IVR CALLS|integer|", "IVRSTATS_QUEUECALLSdata|2|QUEUE CALLS|integer|", "IVRSTATS_QUEUEDROPCALLSdata|3|QUEUE DROP CALLS|integer|", "IVRSTATS_QUEUEDROPPERCENTdata|4|QUEUE DROP PERCENT|percent|", "IVRSTATS_IVRAVGTIMEdata|5|IVR AVG TIME|time|", "IVRSTATS_TOTALAVGTIMEdata|6|TOTAL AVG TIME|time|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title=_QXZ("CALL STATUS STATS"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas; + + $JS_text.="\n"; + if ($report_display_type=="HTML") { $MAIN.=$GRAPH_text; @@ -1145,6 +1185,11 @@ else $MAIN.="
\n"; $MAIN.="\n"; + if ($report_display_type=="HTML") + { + $MAIN.=$JS_text; + } + $MAIN.="\n"; } @@ -1187,12 +1232,8 @@ else exit; } else { - $JS_onload.="}\n"; - if ($report_display_type=='HTML') {$JS_text.=$JS_onload;} - $JS_text.="\n"; echo $HEADER; - echo $JS_text; require("admin_header.php"); echo $MAIN; } diff --git a/agc_2-X/trunk/www/vicidial/AST_LISTS_campaign_stats.php b/agc_2-X/trunk/www/vicidial/AST_LISTS_campaign_stats.php index 8c8eff81..c312fe30 100644 --- a/agc_2-X/trunk/www/vicidial/AST_LISTS_campaign_stats.php +++ b/agc_2-X/trunk/www/vicidial/AST_LISTS_campaign_stats.php @@ -25,6 +25,7 @@ # 150516-1302 - Fixed Javascript element problem, Issue #857 # 151229-2009 - Added archive search option # 160227-1043 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -54,6 +55,7 @@ if (isset($_GET["search_archived_data"])) {$search_archived_data=$_GET["search $report_name = 'Lists Campaign Statuses Report'; $db_source = 'M'; + $JS_text="\n"; +$HEADER.="\n"; $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; @@ -515,13 +520,6 @@ else $CSV_text1.="\""._QXZ("LIST")."\",\""._QXZ("LEADS")."\",\""._QXZ("ACTIVE")."\"\n"; $max_calls=1; $graph_stats=array(); - $GRAPH="
\n"; - $GRAPH.=""; - $GRAPH.="\n"; - $GRAPH.="\n"; - $GRAPH.="\n"; - $GRAPH.="\n"; - $lists_id_str=""; $list_stmt="SELECT list_id from vicidial_lists where active IN('Y','N') $group_SQLand"; $list_rslt=mysql_to_mysqli($list_stmt, $link); @@ -585,19 +583,85 @@ else $OUToutput .= "+------------------------------------------+------------+\n"; $CSV_text1.="\""._QXZ("TOTAL")."\",\"$TOTALleads\"\n"; - for ($d=0; $d".$graph_stats[$d][1]."\n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; + ######### + $graph_array=array("LID_SUMMARYdata|||integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.="
"._QXZ("LIST ID SUMMARY")."
"._QXZ("LIST").""._QXZ("LEADS")."
\"\"".$graph_stats[$d][0]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTALleads)."
\n";
-	# $OUToutput.=$GRAPH;
+
+	$graph_count=count($graph_array);
+	$graph_title=_QXZ("LIST ID SUMMARY");
+	include("graphcanvas.inc");
+	$GRAPH.=$graphCanvas;
 
 
 	##############################
@@ -621,13 +685,6 @@ else
 	$COMP_percent=0;
 
 	$max_calls=1; $graph_stats=array();
-	$GRAPH.="
\n"; - $GRAPH.=""; - $GRAPH.="\n"; - $GRAPH.="\n"; - $GRAPH.="\n"; - $GRAPH.="\n"; - $stmt="select count(*) from ".$vicidial_list_table." where status IN($human_answered_statuses) and list_id IN($list_id_SQL);"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {$MAIN.="$stmt\n";} @@ -743,6 +800,8 @@ else $SC_count = sprintf("%10s", "$SC_count"); while(strlen($SC_count)>10) {$SC_count = substr("$SC_count", 0, -1);} $COMP_count = sprintf("%10s", "$COMP_count"); while(strlen($COMP_count)>10) {$COMP_count = substr("$COMP_count", 0, -1);} + $graph_stats2=array(array("$HA_count", "Human Answer"), array("$SALE_count", "Sale"), array("$DNC_count", "DNC"), array("$CC_count", "Customer Contact"), array("$NI_count", "Not Interested"), array("$UW_count", "Unworkable"), array("$SC_count", "Scheduled Callbacks"), array("$COMP_count", "Completed")); + $OUToutput .= "\n"; $OUToutput .= "\n"; $OUToutput .= "---------- "._QXZ("STATUS FLAGS SUMMARY:",24)." ("._QXZ("and % of leads in selected lists").") "._QXZ("DOWNLOAD")."\n"; @@ -768,43 +827,85 @@ else $CSV_text2 .= "\""._QXZ("Scheduled Callbacks")."\",\"$SC_count\",\"$SC_percent%\"\n"; $CSV_text2 .= "\""._QXZ("Completed")."\",\"$COMP_count\",\"$COMP_percent%\"\n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.="
"._QXZ("STATUS FLAG SUMMARY")."
"._QXZ("STATUS FLAG").""._QXZ("CALLS")."
"._QXZ("Human Answer")."\"\"".$HA_count." ($HA_percent%)
"._QXZ("Sale")."\"\"".$SALE_count." ($SALE_percent%)
"._QXZ("DNC")."\"\"".$DNC_count." ($DNC_percent%)
"._QXZ("Customer Contact")."\"\"".$CC_count." ($CC_percent%)
"._QXZ("Not Interested")."\"\"".$NI_count." ($NI_percent%)
"._QXZ("Unworkable")."\"\"".$UW_count." ($UW_percent%)
"._QXZ("Scheduled Callbacks")."\"\"".$SC_count." ($SC_percent%)
"._QXZ("Completed")."\"\"".$COMP_count." ($COMP_percent%)
"._QXZ("TOTAL").":".trim($flag_count)."
\n";
+		#########
+		$graph_array=array("APDdata|||intpct|");
+		$graph_id++;
+		$default_graph="bar"; # Graph that is initally displayed when page loads
+		include("graph_color_schemas.inc"); 
+
+		$graph_totals_array=array();
+		$graph_totals_rawdata=array();
+		for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n";
+					$chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},";
+					break;
+				case "percent":
+					$graph_totals_array[$q]="";
+					$chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},";
+					break;
+				default:
+					$graph_totals_array[$q]="  "._QXZ("TOTAL").": $current_graph_total\n";
+					$chart_options="options: { legend: { display: false }},";
+					break;
+			}
+
+			$datasets.=$data;
+			$datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT
+			$datasets.="\t\t\t}\n";
+			$datasets.="\t\t]\n";
+			$datasets.="\t}\n";
+
+			$JS_text.=$labels.$datasets;
+			# $JS_text.="}\n";
+			# $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n";
+			$JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n";
+			$JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n";
+		}
+
+		$graph_count=count($graph_array);
+		$graph_title=_QXZ("STATUS FLAG SUMMARY");
+		include("graphcanvas.inc");
+		$GRAPH.=$graphCanvas;
 	# $OUToutput.=$GRAPH;
 
 	##############################
@@ -820,12 +921,6 @@ else
 	$CSV_text3.="\""._QXZ("CATEGORY")."\",\""._QXZ("CALLS")."\",\""._QXZ("DESCRIPTION")."\"\n";
 
 	$max_calls=1; $graph_stats=array();
-	$GRAPH.="
\n"; - $GRAPH.=""; - $GRAPH.="\n"; - $GRAPH.="\n"; - $GRAPH.="\n"; - $GRAPH.="\n"; $TOTCATcalls=0; $r=0; $i=0; @@ -856,18 +951,86 @@ else $OUToutput .= "+----------------------+------------+\n"; $CSV_text3.="\""._QXZ("TOTAL")."\",\"$TOTCATcalls\"\n"; - for ($d=0; $d".$graph_stats[$d][1]."\n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; + ######### + $graph_array=array("CSCSdata|||integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.="
"._QXZ("CUSTOM STATUS CATEGORY STATS")."
"._QXZ("CATEGORY").""._QXZ("CALLS")."
\"\"".$graph_stats[$d][0]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTCATcalls)."
\n";
+
+	$graph_count=count($graph_array);
+	$graph_title=_QXZ("CUSTOM STATUS CATEGORY STATS");
+	include("graphcanvas.inc");
+	$GRAPH.=$graphCanvas;
+
 	#$OUToutput.=$GRAPH;
 
 
@@ -899,14 +1062,6 @@ else
 		$max_flags=1; 
 		$max_status=1;
 		$graph_stats=array();
-		$GRAPH.="

"; - $GRAPH.=""; - $GRAPH.="
"._QXZ("STATUS FLAG BREAKDOWN").""._QXZ("STATUS BREAKDOWN")."

 


"; - $graph_header=""; - $graph_header.=""; - $FLAGS_graph=$graph_header.""; - $STATUS_graph=$graph_header.""; - $CSV_text4.="\""._QXZ("LIST ID").": $LISTIDlists[$i]\",\"$LISTIDlist_names[$i]\",\"$LISTIDlist_active[$i]\"\n"; $CSV_text4.="\""._QXZ("TOTAL LEADS").":\",\"$header_list_count\"\n\n"; @@ -1016,6 +1171,8 @@ else } if ($COMP_count>$max_flags) {$max_flags=$COMP_count;} + $graph_stats2=array(array("$HA_count", "Human Answer"), array("$SALE_count", "Sale"), array("$DNC_count", "DNC"), array("$CC_count", "Customer Contact"), array("$NI_count", "Not Interested"), array("$UW_count", "Unworkable"), array("$SC_count", "Scheduled Callbacks"), array("$COMP_count", "Completed")); + $HA_percent = sprintf("%6.2f", "$HA_percent"); while(strlen($HA_percent)>6) {$HA_percent = substr("$HA_percent", 0, -1);} $SALE_percent = sprintf("%6.2f", "$SALE_percent"); while(strlen($SALE_percent)>6) {$SALE_percent = substr("$SALE_percent", 0, -1);} $DNC_percent = sprintf("%6.2f", "$DNC_percent"); while(strlen($DNC_percent)>6) {$DNC_percent = substr("$DNC_percent", 0, -1);} @@ -1107,25 +1264,103 @@ else $CSV_text4.="\""._QXZ("TOTAL").":\",\"\",\"$TOTALleads\"\n\n\n"; - for ($d=0; $d"; + # USE THIS FOR COMBINED graphs, use pipe-delimited array elements, dataset_name|index|link_name|graph_override + # You have to hard code the graph name in where it is overridden and mind the data indices. No other way to do it. + $multigraph_text=""; + $graph_id++; + $graph_array=array("ALCS_STATUSFLAG$LISTIDlists[$i]data|0|STATUS FLAG BREAKDOWN|intpct|graph_stats2", "ALCS_STATUS$LISTIDlists[$i]data|1|STATUS BREAKDOWN|integer|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $STATUS_graph.="
$LISTIDlists[$i] - $LISTIDlist_names[$i] ($LISTIDlist_active[$i])
"._QXZ("TOTAL LEADS").": $LISTIDcalls[$i]
"._QXZ("FLAG").""._QXZ("COUNT")." / %
"._QXZ("STATUS").""._QXZ("COUNT")."
".$graph_stats[$d][1]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTALleads)."
"; - $JS_onload.="\tDraw".$LISTIDlists[$i]."Graph('FLAGS', '1');\n"; - $JS_text.="function Draw".$LISTIDlists[$i]."Graph(graph, th_id) {\n"; - $JS_text.=" var FLAGS_graph=\"$FLAGS_graph\";\n"; - $JS_text.=" var STATUS_graph=\"$STATUS_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=2; i++) {\n"; - $JS_text.=" var cellID=\"graph".$LISTIDlists[$i]."\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"graph".$LISTIDlists[$i]."\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('status_".$LISTIDlists[$i]."_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; + + $graph_count=count($graph_array); + $graph_title="$LISTIDlists[$i] - $LISTIDlist_names[$i] ($LISTIDlist_active[$i])"; + include("graphcanvas.inc"); + $GRAPH.=$graphCanvas; + # $OUToutput.=$GRAPH; $i++; @@ -1181,9 +1416,9 @@ else $JS_text.="\n"; echo $HEADER; - echo $JS_text; require("admin_header.php"); echo $MAIN; + echo $JS_text; } diff --git a/agc_2-X/trunk/www/vicidial/AST_LISTS_pass_report.php b/agc_2-X/trunk/www/vicidial/AST_LISTS_pass_report.php index fa0ff29a..1e853144 100644 --- a/agc_2-X/trunk/www/vicidial/AST_LISTS_pass_report.php +++ b/agc_2-X/trunk/www/vicidial/AST_LISTS_pass_report.php @@ -15,6 +15,7 @@ # 150516-1303 - Fixed Javascript element problem, Issue #857 # 151125-1640 - Added search archive option # 160227-1138 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -47,6 +48,7 @@ if (isset($_GET["search_archived_data"])) {$search_archived_data=$_GET["search $report_name = 'Lists Pass Report'; $db_source = 'M'; + $JS_text="\n"; +$HEADER.="\n"; $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; @@ -634,187 +639,6 @@ else $graph_stats=array(); $graph_stats2=array(); $max_stats2=array(); - - $GRAPH="
\n"; - $GRAPH.=""; - $GRAPH.="\n"; - $GRAPH.="\n"; - $GRAPH.="\n"; - $GRAPH.="\n"; - - $GRAPH2=" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "; - - $graph_header="
"._QXZ("LIST ID SUMMARY")."
"._QXZ("LIST").""._QXZ("LEADS")."
"._QXZ("CONTACTS 1st PASS").""._QXZ("CONTACTS 2nd PASS").""._QXZ("CONTACTS 3rd PASS").""._QXZ("CONTACTS 4th PASS").""._QXZ("CONTACTS 5th PASS").""._QXZ("CONTACTS LIFE").""._QXZ("CNT RATE 1st PASS").""._QXZ("CNT RATE 2nd PASS").""._QXZ("CNT RATE 3rd PASS").""._QXZ("CNT RATE 4th PASS").""._QXZ("CNT RATE 5th PASS").""._QXZ("CNT RATE LIFE").""._QXZ("SALES 1st PASS").""._QXZ("SALES 2nd PASS").""._QXZ("SALES 3rd PASS").""._QXZ("SALES 4th PASS").""._QXZ("SALES 5th PASS").""._QXZ("SALES LIFE").""._QXZ("CONV RATE 1st PASS").""._QXZ("CONV RATE 2nd PASS").""._QXZ("CONV RATE 3rd PASS").""._QXZ("CONV RATE 4th PASS").""._QXZ("CONV RATE 5th PASS").""._QXZ("CONV RATE LIFE").""._QXZ("DNC 1st PASS").""._QXZ("DNC 2nd PASS").""._QXZ("DNC 3rd PASS").""._QXZ("DNC 4th PASS").""._QXZ("DNC 5th PASS").""._QXZ("DNC LIFE").""._QXZ("DNC RATE 1st PASS").""._QXZ("DNC RATE 2nd PASS").""._QXZ("DNC RATE 3rd PASS").""._QXZ("DNC RATE 4th PASS").""._QXZ("DNC RATE 5th PASS").""._QXZ("DNC RATE LIFE").""._QXZ("CUST CNT 1st PASS").""._QXZ("CUST CNT 2nd PASS").""._QXZ("CUST CNT 3rd PASS").""._QXZ("CUST CNT 4th PASS").""._QXZ("CUST CNT 5th PASS").""._QXZ("CUST CNT LIFE").""._QXZ("CUST CUSTCNT RATE 1st PASS").""._QXZ("CUST CUSTCNT RATE 2nd PASS").""._QXZ("CUST CUSTCNT RATE 3rd PASS").""._QXZ("CUST CUSTCNT RATE 4th PASS").""._QXZ("CUST CUSTCNT RATE 5th PASS").""._QXZ("CUST CUSTCNT RATE LIFE").""._QXZ("UNWRK 1st PASS").""._QXZ("UNWRK 2nd PASS").""._QXZ("UNWRK 3rd PASS").""._QXZ("UNWRK 4th PASS").""._QXZ("UNWRK 5th PASS").""._QXZ("UNWRK LIFE").""._QXZ("UNWRK RATE 1st PASS").""._QXZ("UNWRK RATE 2nd PASS").""._QXZ("UNWRK RATE 3rd PASS").""._QXZ("UNWRK RATE 4th PASS").""._QXZ("UNWRK RATE 5th PASS").""._QXZ("UNWRK RATE LIFE").""._QXZ("SCHD CLBK 1st PASS").""._QXZ("SCHD CLBK 2nd PASS").""._QXZ("SCHD CLBK 3rd PASS").""._QXZ("SCHD CLBK 4th PASS").""._QXZ("SCHD CLBK 5th PASS").""._QXZ("SCHD CLBK LIFE").""._QXZ("SCHD CLBK RATE 1st PASS").""._QXZ("SCHD CLBK RATE 2nd PASS").""._QXZ("SCHD CLBK RATE 3rd PASS").""._QXZ("SCHD CLBK RATE 4th PASS").""._QXZ("SCHD CLBK RATE 5th PASS").""._QXZ("SCHD CLBK RATE LIFE").""._QXZ("COMPLTD 1st PASS").""._QXZ("COMPLTD 2nd PASS").""._QXZ("COMPLTD 3rd PASS").""._QXZ("COMPLTD 4th PASS").""._QXZ("COMPLTD 5th PASS").""._QXZ("COMPLTD LIFE").""._QXZ("COMPLTD RATE 1st PASS").""._QXZ("COMPLTD RATE 2nd PASS").""._QXZ("COMPLTD RATE 3rd PASS").""._QXZ("COMPLTD RATE 4th PASS").""._QXZ("COMPLTD RATE 5th PASS").""._QXZ("COMPLTD RATE LIFE")."
"; - $CONTACTS1_graph=$graph_header.""; - $CONTACTS2_graph=$graph_header.""; - $CONTACTS3_graph=$graph_header.""; - $CONTACTS4_graph=$graph_header.""; - $CONTACTS5_graph=$graph_header.""; - $CONTACTSALL_graph=$graph_header.""; - $CNTRATE1_graph=$graph_header.""; - $CNTRATE2_graph=$graph_header.""; - $CNTRATE3_graph=$graph_header.""; - $CNTRATE4_graph=$graph_header.""; - $CNTRATE5_graph=$graph_header.""; - $CNTRATEALL_graph=$graph_header.""; - $SALES1_graph=$graph_header.""; - $SALES2_graph=$graph_header.""; - $SALES3_graph=$graph_header.""; - $SALES4_graph=$graph_header.""; - $SALES5_graph=$graph_header.""; - $SALESALL_graph=$graph_header.""; - $CONVRATE1_graph=$graph_header.""; - $CONVRATE2_graph=$graph_header.""; - $CONVRATE3_graph=$graph_header.""; - $CONVRATE4_graph=$graph_header.""; - $CONVRATE5_graph=$graph_header.""; - $CONVRATEALL_graph=$graph_header.""; - $DNC1_graph=$graph_header.""; - $DNC2_graph=$graph_header.""; - $DNC3_graph=$graph_header.""; - $DNC4_graph=$graph_header.""; - $DNC5_graph=$graph_header.""; - $DNCALL_graph=$graph_header.""; - $DNCRATE1_graph=$graph_header.""; - $DNCRATE2_graph=$graph_header.""; - $DNCRATE3_graph=$graph_header.""; - $DNCRATE4_graph=$graph_header.""; - $DNCRATE5_graph=$graph_header.""; - $DNCRATEALL_graph=$graph_header.""; - $CUSTCNT1_graph=$graph_header.""; - $CUSTCNT2_graph=$graph_header.""; - $CUSTCNT3_graph=$graph_header.""; - $CUSTCNT4_graph=$graph_header.""; - $CUSTCNT5_graph=$graph_header.""; - $CUSTCNTALL_graph=$graph_header.""; - $CUSTCNTRATE1_graph=$graph_header.""; - $CUSTCNTRATE2_graph=$graph_header.""; - $CUSTCNTRATE3_graph=$graph_header.""; - $CUSTCNTRATE4_graph=$graph_header.""; - $CUSTCNTRATE5_graph=$graph_header.""; - $CUSTCNTRATEALL_graph=$graph_header.""; - $UNWRK1_graph=$graph_header.""; - $UNWRK2_graph=$graph_header.""; - $UNWRK3_graph=$graph_header.""; - $UNWRK4_graph=$graph_header.""; - $UNWRK5_graph=$graph_header.""; - $UNWRKALL_graph=$graph_header.""; - $UNWRKRATE1_graph=$graph_header.""; - $UNWRKRATE2_graph=$graph_header.""; - $UNWRKRATE3_graph=$graph_header.""; - $UNWRKRATE4_graph=$graph_header.""; - $UNWRKRATE5_graph=$graph_header.""; - $UNWRKRATEALL_graph=$graph_header.""; - $SCHDCLBK1_graph=$graph_header.""; - $SCHDCLBK2_graph=$graph_header.""; - $SCHDCLBK3_graph=$graph_header.""; - $SCHDCLBK4_graph=$graph_header.""; - $SCHDCLBK5_graph=$graph_header.""; - $SCHDCLBKALL_graph=$graph_header.""; - $SCHDCLBKRATE1_graph=$graph_header.""; - $SCHDCLBKRATE2_graph=$graph_header.""; - $SCHDCLBKRATE3_graph=$graph_header.""; - $SCHDCLBKRATE4_graph=$graph_header.""; - $SCHDCLBKRATE5_graph=$graph_header.""; - $SCHDCLBKRATEALL_graph=$graph_header.""; - $COMPLTD1_graph=$graph_header.""; - $COMPLTD2_graph=$graph_header.""; - $COMPLTD3_graph=$graph_header.""; - $COMPLTD4_graph=$graph_header.""; - $COMPLTD5_graph=$graph_header.""; - $COMPLTDALL_graph=$graph_header.""; - $COMPLTDRATE1_graph=$graph_header.""; - $COMPLTDRATE2_graph=$graph_header.""; - $COMPLTDRATE3_graph=$graph_header.""; - $COMPLTDRATE4_graph=$graph_header.""; - $COMPLTDRATE5_graph=$graph_header.""; - $COMPLTDRATEALL_graph=$graph_header.""; - $lists_id_str=""; $list_stmt="SELECT list_id from vicidial_lists where active IN('Y','N') $group_SQLand"; $list_rslt=mysql_to_mysqli($list_stmt, $link); @@ -2125,294 +1949,165 @@ else $totals2[83]=$MR_five_count_totS; $totals2[84]=$MR_count_totS; - for ($d=0; $d"; - $CONTACTS2_graph.=" "; - $CONTACTS3_graph.=" "; - $CONTACTS4_graph.=" "; - $CONTACTS5_graph.=" "; - $CONTACTSALL_graph.=" "; - $CNTRATE1_graph.=" "; - $CNTRATE2_graph.=" "; - $CNTRATE3_graph.=" "; - $CNTRATE4_graph.=" "; - $CNTRATE5_graph.=" "; - $CNTRATEALL_graph.=" "; - $SALES1_graph.=" "; - $SALES2_graph.=" "; - $SALES3_graph.=" "; - $SALES4_graph.=" "; - $SALES5_graph.=" "; - $SALESALL_graph.=" "; - $CONVRATE1_graph.=" "; - $CONVRATE2_graph.=" "; - $CONVRATE3_graph.=" "; - $CONVRATE4_graph.=" "; - $CONVRATE5_graph.=" "; - $CONVRATEALL_graph.=" "; - $DNC1_graph.=" "; - $DNC2_graph.=" "; - $DNC3_graph.=" "; - $DNC4_graph.=" "; - $DNC5_graph.=" "; - $DNCALL_graph.=" "; - $DNCRATE1_graph.=" "; - $DNCRATE2_graph.=" "; - $DNCRATE3_graph.=" "; - $DNCRATE4_graph.=" "; - $DNCRATE5_graph.=" "; - $DNCRATEALL_graph.=" "; - $CUSTCNT1_graph.=" "; - $CUSTCNT2_graph.=" "; - $CUSTCNT3_graph.=" "; - $CUSTCNT4_graph.=" "; - $CUSTCNT5_graph.=" "; - $CUSTCNTALL_graph.=" "; - $CUSTCNTRATE1_graph.=" "; - $CUSTCNTRATE2_graph.=" "; - $CUSTCNTRATE3_graph.=" "; - $CUSTCNTRATE4_graph.=" "; - $CUSTCNTRATE5_graph.=" "; - $CUSTCNTRATEALL_graph.=" "; - $UNWRK1_graph.=" "; - $UNWRK2_graph.=" "; - $UNWRK3_graph.=" "; - $UNWRK4_graph.=" "; - $UNWRK5_graph.=" "; - $UNWRKALL_graph.=" "; - $UNWRKRATE1_graph.=" "; - $UNWRKRATE2_graph.=" "; - $UNWRKRATE3_graph.=" "; - $UNWRKRATE4_graph.=" "; - $UNWRKRATE5_graph.=" "; - $UNWRKRATEALL_graph.=" "; - $SCHDCLBK1_graph.=" "; - $SCHDCLBK2_graph.=" "; - $SCHDCLBK3_graph.=" "; - $SCHDCLBK4_graph.=" "; - $SCHDCLBK5_graph.=" "; - $SCHDCLBKALL_graph.=" "; - $SCHDCLBKRATE1_graph.=" "; - $SCHDCLBKRATE2_graph.=" "; - $SCHDCLBKRATE3_graph.=" "; - $SCHDCLBKRATE4_graph.=" "; - $SCHDCLBKRATE5_graph.=" "; - $SCHDCLBKRATEALL_graph.=" "; - $COMPLTD1_graph.=" "; - $COMPLTD2_graph.=" "; - $COMPLTD3_graph.=" "; - $COMPLTD4_graph.=" "; - $COMPLTD5_graph.=" "; - $COMPLTDALL_graph.=" "; - $COMPLTDRATE1_graph.=" "; - $COMPLTDRATE2_graph.=" "; - $COMPLTDRATE3_graph.=" "; - $COMPLTDRATE4_graph.=" "; - $COMPLTDRATE5_graph.=" "; - $COMPLTDRATEALL_graph.=" "; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("LIS_CONTACTS1data|1|CONTACTS 1st PASS|integer|", "LIS_CONTACTS2data|2|CONTACTS 2nd PASS|integer|", "LIS_CONTACTS3data|3|CONTACTS 3rd PASS|integer|", "LIS_CONTACTS4data|4|CONTACTS 4th PASS|integer|", "LIS_CONTACTS5data|5|CONTACTS 5th PASS|integer|", "LIS_CONTACTSLIFEdata|6|CONTACTS LIFE|integer|", "LIS_CNTRATE1data|7|CNT RATE 1st PASS|decimal|", "LIS_CNTRATE2data|8|CNT RATE 2nd PASS|decimal|", "LIS_CNTRATE3data|9|CNT RATE 3rd PASS|decimal|", "LIS_CNTRATE4data|10|CNT RATE 4th PASS|decimal|", "LIS_CNTRATE5data|11|CNT RATE 5th PASS|decimal|", "LIS_CNTRATELIFEdata|12|CNT RATE LIFE|decimal|", "LIS_SALES1data|13|SALES 1st PASS|integer|", "LIS_SALES2data|14|SALES 2nd PASS|integer|", "LIS_SALES3data|15|SALES 3rd PASS|integer|", "LIS_SALES4data|16|SALES 4th PASS|integer|", "LIS_SALES5data|17|SALES 5th PASS|integer|", "LIS_SALESLIFEdata|18|SALES LIFE|integer|", "LIS_CONVRATE1data|19|CONV RATE 1st PASS|decimal|", "LIS_CONVRATE2data|20|CONV RATE 2nd PASS|decimal|", "LIS_CONVRATE3data|21|CONV RATE 3rd PASS|decimal|", "LIS_CONVRATE4data|22|CONV RATE 4th PASS|decimal|", "LIS_CONVRATE5data|23|CONV RATE 5th PASS|decimal|", "LIS_CONVLIFE1data|24|CONV RATE LIFE|decimal|", "LIS_DNC1data|25|DNC 1st PASS|integer|", "LIS_DNC2data|26|DNC 2nd PASS|integer|", "LIS_DNC3data|27|DNC 3rd PASS|integer|", "LIS_DNC4data|28|DNC 4th PASS|integer|", "LIS_DNC5data|29|DNC 5th PASS|integer|", "LIS_DNCLIFEdata|30|DNC LIFE|integer|", "LIS_DNCRATE1data|31|DNC RATE 1st PASS|decimal|", "LIS_DNCRATE2data|32|DNC RATE 2nd PASS|decimal|", "LIS_DNCRATE3data|33|DNC RATE 3rd PASS|decimal|", "LIS_DNCRATE4data|34|DNC RATE 4th PASS|decimal|", "LIS_DNCRATE5data|35|DNC RATE 5th PASS|decimal|", "LIS_DNCRATELIFEdata|36|DNC RATE LIFE|decimal|", "LIS_CUSTCNT1data|37|CUST CNT 1st PASS|integer|", "LIS_CUSTCNT2data|38|CUST CNT 2nd PASS|integer|", "LIS_CUSTCNT3data|39|CUST CNT 3rd PASS|integer|", "LIS_CUSTCNT4data|40|CUST CNT 4th PASS|integer|", "LIS_CUSTCNT5data|41|CUST CNT 5th PASS|integer|", "LIS_CUSTCNTLIFEdata|42|CUST CNT LIFE|integer|", "LIS_CUSCNTRATE1data|43|CUST CUSTCNT RATE 1st PASS|decimal|", "LIS_CUSCNTRATE2data|44|CUST CUSTCNT RATE 2nd PASS|decimal|", "LIS_CUSCNTRATE3data|45|CUST CUSTCNT RATE 3rd PASS|decimal|", "LIS_CUSCNTRATE4data|46|CUST CUSTCNT RATE 4th PASS|decimal|", "LIS_CUSCNTRATE5data|47|CUST CUSTCNT RATE 5th PASS|decimal|", "LIS_CUSCNTRATELIFEdata|48|CUST CUSTCNT RATE LIFE|decimal|", "LIS_UNWRK1data|49|UNWRK 1st PASS|integer|", "LIS_UNWRK2data|50|UNWRK 2nd PASS|integer|", "LIS_UNWRK3data|51|UNWRK 3rd PASS|integer|", "LIS_UNWRK4data|52|UNWRK 4th PASS|integer|", "LIS_UNWRK5data|53|UNWRK 5th PASS|integer|", "LIS_UNWRKLIFEdata|54|UNWRK LIFE|integer|", "LIS_UNWRKRATE1data|55|UNWRK RATE 1st PASS|decimal|", "LIS_UNWRKRATE2data|56|UNWRK RATE 2nd PASS|decimal|", "LIS_UNWRKRATE3data|57|UNWRK RATE 3rd PASS|decimal|", "LIS_UNWRKRATE4data|58|UNWRK RATE 4th PASS|decimal|", "LIS_UNWRKRATE5data|59|UNWRK RATE 5th PASS|decimal|", "LIS_UNWRKRATELIFEdata|60|UNWRK RATE LIFE|decimal|", "LIS_SCHDCLBK1data|61|SCHD CLBK 1st PASS|integer|", "LIS_SCHDCLBK2data|62|SCHD CLBK 2nd PASS|integer|", "LIS_SCHDCLBK3data|63|SCHD CLBK 3rd PASS|integer|", "LIS_SCHDCLBK4data|64|SCHD CLBK 4th PASS|integer|", "LIS_SCHDCLBK5data|65|SCHD CLBK 5th PASS|integer|", "LIS_SCHDCLBKLIFEdata|66|SCHD CLBK LIFE|integer|", "LIS_SCHDCLBKRATE1data|67|SCHD CLBK RATE 1st PASS|decimal|", "LIS_SCHDCLBKRATE2data|68|SCHD CLBK RATE 2nd PASS|decimal|", "LIS_SCHDCLBKRATE3data|69|SCHD CLBK RATE 3rd PASS|decimal|", "LIS_SCHDCLBKRATE4data|70|SCHD CLBK RATE 4th PASS|decimal|", "LIS_SCHDCLBKRATE5data|71|SCHD CLBK RATE 5th PASS|decimal|", "LIS_SCHDCLBKRATELIFEdata|72|SCHD CLBK RATE LIFE|decimal|", "LIS_COMPLTD1data|73|COMPLTD 1st PASS|integer|", "LIS_COMPLTD2data|74|COMPLTD 2nd PASS|integer|", "LIS_COMPLTD3data|75|COMPLTD 3rd PASS|integer|", "LIS_COMPLTD4data|76|COMPLTD 4th PASS|integer|", "LIS_COMPLTD5data|77|COMPLTD 5th PASS|integer|", "LIS_COMPLTDLIFEdata|78|COMPLTD LIFE|integer|", "LIS_COMPLTDRATE1data|79|COMPLTD RATE 1st PASS|decimal|", "LIS_COMPLTDRATE2data|80|COMPLTD RATE 2nd PASS|decimal|", "LIS_COMPLTDRATE3data|81|COMPLTD RATE 3rd PASS|decimal|", "LIS_COMPLTDRATE4data|82|COMPLTD RATE 4th PASS|decimal|", "LIS_COMPLTDRATE5data|83|COMPLTD RATE 5th PASS|decimal|", "LIS_COMPLTDRATELIFEdata|84|COMPLTD RATE LIFE|decimal|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $CONTACTS1_graph.=" "; - $CONTACTS2_graph.=" "; - $CONTACTS3_graph.=" "; - $CONTACTS4_graph.=" "; - $CONTACTS5_graph.=" "; - $CONTACTSALL_graph.=" "; - $CNTRATE1_graph.=" "; - $CNTRATE2_graph.=" "; - $CNTRATE3_graph.=" "; - $CNTRATE4_graph.=" "; - $CNTRATE5_graph.=" "; - $CNTRATEALL_graph.=" "; - $SALES1_graph.=" "; - $SALES2_graph.=" "; - $SALES3_graph.=" "; - $SALES4_graph.=" "; - $SALES5_graph.=" "; - $SALESALL_graph.=" "; - $CONVRATE1_graph.=" "; - $CONVRATE2_graph.=" "; - $CONVRATE3_graph.=" "; - $CONVRATE4_graph.=" "; - $CONVRATE5_graph.=" "; - $CONVRATEALL_graph.=" "; - $DNC1_graph.=" "; - $DNC2_graph.=" "; - $DNC3_graph.=" "; - $DNC4_graph.=" "; - $DNC5_graph.=" "; - $DNCALL_graph.=" "; - $DNCRATE1_graph.=" "; - $DNCRATE2_graph.=" "; - $DNCRATE3_graph.=" "; - $DNCRATE4_graph.=" "; - $DNCRATE5_graph.=" "; - $DNCRATEALL_graph.=" "; - $CUSTCNT1_graph.=" "; - $CUSTCNT2_graph.=" "; - $CUSTCNT3_graph.=" "; - $CUSTCNT4_graph.=" "; - $CUSTCNT5_graph.=" "; - $CUSTCNTALL_graph.=" "; - $CUSTCNTRATE1_graph.=" "; - $CUSTCNTRATE2_graph.=" "; - $CUSTCNTRATE3_graph.=" "; - $CUSTCNTRATE4_graph.=" "; - $CUSTCNTRATE5_graph.=" "; - $CUSTCNTRATEALL_graph.=" "; - $UNWRK1_graph.=" "; - $UNWRK2_graph.=" "; - $UNWRK3_graph.=" "; - $UNWRK4_graph.=" "; - $UNWRK5_graph.=" "; - $UNWRKALL_graph.=" "; - $UNWRKRATE1_graph.=" "; - $UNWRKRATE2_graph.=" "; - $UNWRKRATE3_graph.=" "; - $UNWRKRATE4_graph.=" "; - $UNWRKRATE5_graph.=" "; - $UNWRKRATEALL_graph.=" "; - $SCHDCLBK1_graph.=" "; - $SCHDCLBK2_graph.=" "; - $SCHDCLBK3_graph.=" "; - $SCHDCLBK4_graph.=" "; - $SCHDCLBK5_graph.=" "; - $SCHDCLBKALL_graph.=" "; - $SCHDCLBKRATE1_graph.=" "; - $SCHDCLBKRATE2_graph.=" "; - $SCHDCLBKRATE3_graph.=" "; - $SCHDCLBKRATE4_graph.=" "; - $SCHDCLBKRATE5_graph.=" "; - $SCHDCLBKRATEALL_graph.=" "; - $COMPLTD1_graph.=" "; - $COMPLTD2_graph.=" "; - $COMPLTD3_graph.=" "; - $COMPLTD4_graph.=" "; - $COMPLTD5_graph.=" "; - $COMPLTDALL_graph.=" "; - $COMPLTDRATE1_graph.=" "; - $COMPLTDRATE2_graph.=" "; - $COMPLTDRATE3_graph.=" "; - $COMPLTDRATE4_graph.=" "; - $COMPLTDRATE5_graph.=" "; - $COMPLTDRATEALL_graph.=" "; + $graph_count=count($graph_array); + $graph_title=_QXZ("LIST ID SUMMARY"); + include("graphcanvas.inc"); + $GRAPH2.=$graphCanvas; + ######### + $graph_array=array("ALRdata|||integer|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); - $JS_onload.="\tDrawGraph('CONTACTS1', '1');\n"; - $JS_text.="function DrawGraph(graph, th_id) {\n"; - $JS_text.=" var graph_CONTACTS1=\"$CONTACTS1_graph\";\n"; - $JS_text.=" var graph_CONTACTS2=\"$CONTACTS2_graph\";\n"; - $JS_text.=" var graph_CONTACTS3=\"$CONTACTS3_graph\";\n"; - $JS_text.=" var graph_CONTACTS4=\"$CONTACTS4_graph\";\n"; - $JS_text.=" var graph_CONTACTS5=\"$CONTACTS5_graph\";\n"; - $JS_text.=" var graph_CONTACTSALL=\"$CONTACTSALL_graph\";\n"; - $JS_text.=" var graph_CNTRATE1=\"$CNTRATE1_graph\";\n"; - $JS_text.=" var graph_CNTRATE2=\"$CNTRATE2_graph\";\n"; - $JS_text.=" var graph_CNTRATE3=\"$CNTRATE3_graph\";\n"; - $JS_text.=" var graph_CNTRATE4=\"$CNTRATE4_graph\";\n"; - $JS_text.=" var graph_CNTRATE5=\"$CNTRATE5_graph\";\n"; - $JS_text.=" var graph_CNTRATEALL=\"$CNTRATEALL_graph\";\n"; - $JS_text.=" var graph_SALES1=\"$SALES1_graph\";\n"; - $JS_text.=" var graph_SALES2=\"$SALES2_graph\";\n"; - $JS_text.=" var graph_SALES3=\"$SALES3_graph\";\n"; - $JS_text.=" var graph_SALES4=\"$SALES4_graph\";\n"; - $JS_text.=" var graph_SALES5=\"$SALES5_graph\";\n"; - $JS_text.=" var graph_SALESALL=\"$SALESALL_graph\";\n"; - $JS_text.=" var graph_CONVRATE1=\"$CONVRATE1_graph\";\n"; - $JS_text.=" var graph_CONVRATE2=\"$CONVRATE2_graph\";\n"; - $JS_text.=" var graph_CONVRATE3=\"$CONVRATE3_graph\";\n"; - $JS_text.=" var graph_CONVRATE4=\"$CONVRATE4_graph\";\n"; - $JS_text.=" var graph_CONVRATE5=\"$CONVRATE5_graph\";\n"; - $JS_text.=" var graph_CONVRATEALL=\"$CONVRATEALL_graph\";\n"; - $JS_text.=" var graph_DNC1=\"$DNC1_graph\";\n"; - $JS_text.=" var graph_DNC2=\"$DNC2_graph\";\n"; - $JS_text.=" var graph_DNC3=\"$DNC3_graph\";\n"; - $JS_text.=" var graph_DNC4=\"$DNC4_graph\";\n"; - $JS_text.=" var graph_DNC5=\"$DNC5_graph\";\n"; - $JS_text.=" var graph_DNCALL=\"$DNCALL_graph\";\n"; - $JS_text.=" var graph_DNCRATE1=\"$DNCRATE1_graph\";\n"; - $JS_text.=" var graph_DNCRATE2=\"$DNCRATE2_graph\";\n"; - $JS_text.=" var graph_DNCRATE3=\"$DNCRATE3_graph\";\n"; - $JS_text.=" var graph_DNCRATE4=\"$DNCRATE4_graph\";\n"; - $JS_text.=" var graph_DNCRATE5=\"$DNCRATE5_graph\";\n"; - $JS_text.=" var graph_DNCRATEALL=\"$DNCRATEALL_graph\";\n"; - $JS_text.=" var graph_CUSTCNT1=\"$CUSTCNT1_graph\";\n"; - $JS_text.=" var graph_CUSTCNT2=\"$CUSTCNT2_graph\";\n"; - $JS_text.=" var graph_CUSTCNT3=\"$CUSTCNT3_graph\";\n"; - $JS_text.=" var graph_CUSTCNT4=\"$CUSTCNT4_graph\";\n"; - $JS_text.=" var graph_CUSTCNT5=\"$CUSTCNT5_graph\";\n"; - $JS_text.=" var graph_CUSTCNTALL=\"$CUSTCNTALL_graph\";\n"; - $JS_text.=" var graph_CUSTCNTRATE1=\"$CUSTCNTRATE1_graph\";\n"; - $JS_text.=" var graph_CUSTCNTRATE2=\"$CUSTCNTRATE2_graph\";\n"; - $JS_text.=" var graph_CUSTCNTRATE3=\"$CUSTCNTRATE3_graph\";\n"; - $JS_text.=" var graph_CUSTCNTRATE4=\"$CUSTCNTRATE4_graph\";\n"; - $JS_text.=" var graph_CUSTCNTRATE5=\"$CUSTCNTRATE5_graph\";\n"; - $JS_text.=" var graph_CUSTCNTRATEALL=\"$CUSTCNTRATEALL_graph\";\n"; - $JS_text.=" var graph_UNWRK1=\"$UNWRK1_graph\";\n"; - $JS_text.=" var graph_UNWRK2=\"$UNWRK2_graph\";\n"; - $JS_text.=" var graph_UNWRK3=\"$UNWRK3_graph\";\n"; - $JS_text.=" var graph_UNWRK4=\"$UNWRK4_graph\";\n"; - $JS_text.=" var graph_UNWRK5=\"$UNWRK5_graph\";\n"; - $JS_text.=" var graph_UNWRKALL=\"$UNWRKALL_graph\";\n"; - $JS_text.=" var graph_UNWRKRATE1=\"$UNWRKRATE1_graph\";\n"; - $JS_text.=" var graph_UNWRKRATE2=\"$UNWRKRATE2_graph\";\n"; - $JS_text.=" var graph_UNWRKRATE3=\"$UNWRKRATE3_graph\";\n"; - $JS_text.=" var graph_UNWRKRATE4=\"$UNWRKRATE4_graph\";\n"; - $JS_text.=" var graph_UNWRKRATE5=\"$UNWRKRATE5_graph\";\n"; - $JS_text.=" var graph_UNWRKRATEALL=\"$UNWRKRATEALL_graph\";\n"; - $JS_text.=" var graph_SCHDCLBK1=\"$SCHDCLBK1_graph\";\n"; - $JS_text.=" var graph_SCHDCLBK2=\"$SCHDCLBK2_graph\";\n"; - $JS_text.=" var graph_SCHDCLBK3=\"$SCHDCLBK3_graph\";\n"; - $JS_text.=" var graph_SCHDCLBK4=\"$SCHDCLBK4_graph\";\n"; - $JS_text.=" var graph_SCHDCLBK5=\"$SCHDCLBK5_graph\";\n"; - $JS_text.=" var graph_SCHDCLBKALL=\"$SCHDCLBKALL_graph\";\n"; - $JS_text.=" var graph_SCHDCLBKRATE1=\"$SCHDCLBKRATE1_graph\";\n"; - $JS_text.=" var graph_SCHDCLBKRATE2=\"$SCHDCLBKRATE2_graph\";\n"; - $JS_text.=" var graph_SCHDCLBKRATE3=\"$SCHDCLBKRATE3_graph\";\n"; - $JS_text.=" var graph_SCHDCLBKRATE4=\"$SCHDCLBKRATE4_graph\";\n"; - $JS_text.=" var graph_SCHDCLBKRATE5=\"$SCHDCLBKRATE5_graph\";\n"; - $JS_text.=" var graph_SCHDCLBKRATEALL=\"$SCHDCLBKRATEALL_graph\";\n"; - $JS_text.=" var graph_COMPLTD1=\"$COMPLTD1_graph\";\n"; - $JS_text.=" var graph_COMPLTD2=\"$COMPLTD2_graph\";\n"; - $JS_text.=" var graph_COMPLTD3=\"$COMPLTD3_graph\";\n"; - $JS_text.=" var graph_COMPLTD4=\"$COMPLTD4_graph\";\n"; - $JS_text.=" var graph_COMPLTD5=\"$COMPLTD5_graph\";\n"; - $JS_text.=" var graph_COMPLTDALL=\"$COMPLTDALL_graph\";\n"; - $JS_text.=" var graph_COMPLTDRATE1=\"$COMPLTDRATE1_graph\";\n"; - $JS_text.=" var graph_COMPLTDRATE2=\"$COMPLTDRATE2_graph\";\n"; - $JS_text.=" var graph_COMPLTDRATE3=\"$COMPLTDRATE3_graph\";\n"; - $JS_text.=" var graph_COMPLTDRATE4=\"$COMPLTDRATE4_graph\";\n"; - $JS_text.=" var graph_COMPLTDRATE5=\"$COMPLTDRATE5_graph\";\n"; - $JS_text.=" var graph_COMPLTDRATEALL=\"$COMPLTDRATEALL_graph\";\n"; + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; - for ($d=0; $d".$graph_stats[$d][1]."\n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; - $GRAPH.="
"._QXZ("LIST ID SUMMARY")."
"._QXZ("LISTS").""._QXZ("CONTACTS 1st PASS")."
"._QXZ("CONTACTS 2nd PASS")."
"._QXZ("CONTACTS 3rd PASS")."
"._QXZ("CONTACTS 4th PASS")."
"._QXZ("CONTACTS 5th PASS")."
"._QXZ("CONTACTS LIFE")."
"._QXZ("CNT RATE 1st PASS")."
"._QXZ("CNT RATE 2nd PASS")."
"._QXZ("CNT RATE 3rd PASS")."
"._QXZ("CNT RATE 4th PASS")."
"._QXZ("CNT RATE 5th PASS")."
"._QXZ("CNT RATE LIFE")."
"._QXZ("SALES 1st PASS")."
"._QXZ("SALES 2nd PASS")."
"._QXZ("SALES 3rd PASS")."
"._QXZ("SALES 4th PASS")."
"._QXZ("SALES 5th PASS")."
"._QXZ("SALES LIFE")."
"._QXZ("CONV RATE 1st PASS")."
"._QXZ("CONV RATE 2nd PASS")."
"._QXZ("CONV RATE 3rd PASS")."
"._QXZ("CONV RATE 4th PASS")."
"._QXZ("CONV RATE 5th PASS")."
"._QXZ("CONV RATE LIFE")."
"._QXZ("DNC 1st PASS")."
"._QXZ("DNC 2nd PASS")."
"._QXZ("DNC 3rd PASS")."
"._QXZ("DNC 4th PASS")."
"._QXZ("DNC 5th PASS")."
"._QXZ("DNC LIFE")."
"._QXZ("DNC RATE 1st PASS")."
"._QXZ("DNC RATE 2nd PASS")."
"._QXZ("DNC RATE 3rd PASS")."
"._QXZ("DNC RATE 4th PASS")."
"._QXZ("DNC RATE 5th PASS")."
"._QXZ("DNC RATE LIFE")."
"._QXZ("CUST CNT 1st PASS")."
"._QXZ("CUST CNT 2nd PASS")."
"._QXZ("CUST CNT 3rd PASS")."
"._QXZ("CUST CNT 4th PASS")."
"._QXZ("CUST CNT 5th PASS")."
"._QXZ("CUST CNT LIFE")."
"._QXZ("CUST CUSTCNT RATE 1st PASS")."
"._QXZ("CUST CUSTCNT RATE 2nd PASS")."
"._QXZ("CUST CUSTCNT RATE 3rd PASS")."
"._QXZ("CUST CUSTCNT RATE 4th PASS")."
"._QXZ("CUST CUSTCNT RATE 5th PASS")."
"._QXZ("CUST CUSTCNT RATE LIFE")."
"._QXZ("UNWRK 1st PASS")."
"._QXZ("UNWRK 2nd PASS")."
"._QXZ("UNWRK 3rd PASS")."
"._QXZ("UNWRK 4th PASS")."
"._QXZ("UNWRK 5th PASS")."
"._QXZ("UNWRK LIFE")."
"._QXZ("UNWRK RATE 1st PASS")."
"._QXZ("UNWRK RATE 2nd PASS")."
"._QXZ("UNWRK RATE 3rd PASS")."
"._QXZ("UNWRK RATE 4th PASS")."
"._QXZ("UNWRK RATE 5th PASS")."
"._QXZ("UNWRK RATE LIFE")."
"._QXZ("SCHD CLBK 1st PASS")."
"._QXZ("SCHD CLBK 2nd PASS")."
"._QXZ("SCHD CLBK 3rd PASS")."
"._QXZ("SCHD CLBK 4th PASS")."
"._QXZ("SCHD CLBK 5th PASS")."
"._QXZ("SCHD CLBK LIFE")."
"._QXZ("SCHD CLBK RATE 1st PASS")."
"._QXZ("SCHD CLBK RATE 2nd PASS")."
"._QXZ("SCHD CLBK RATE 3rd PASS")."
"._QXZ("SCHD CLBK RATE 4th PASS")."
"._QXZ("SCHD CLBK RATE 5th PASS")."
"._QXZ("SCHD CLBK RATE LIFE")."
"._QXZ("COMPLTD 1st PASS")."
"._QXZ("COMPLTD 2nd PASS")."
"._QXZ("COMPLTD 3rd PASS")."
"._QXZ("COMPLTD 4th PASS")."
"._QXZ("COMPLTD 5th PASS")."
"._QXZ("COMPLTD LIFE")."
"._QXZ("COMPLTD RATE 1st PASS")."
"._QXZ("COMPLTD RATE 2nd PASS")."
"._QXZ("COMPLTD RATE 3rd PASS")."
"._QXZ("COMPLTD RATE 4th PASS")."
"._QXZ("COMPLTD RATE 5th PASS")."
"._QXZ("COMPLTD RATE LIFE")."
MathZDC(800*".$graph_stats2[$d][1].", $max_stats2[$d])".$graph_stats2[$d][1]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][2]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][3]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][4]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][5]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][6]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][7]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][8]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][9]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][10]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][11]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][12]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][13]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][14]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][15]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][16]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][17]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][18]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][19]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][20]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][21]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][22]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][23]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][24]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][25]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][26]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][27]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][28]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][29]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][30]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][31]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][32]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][33]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][34]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][35]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][36]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][37]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][38]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][39]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][40]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][41]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][42]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][43]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][44]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][45]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][46]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][47]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][48]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][49]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][50]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][51]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][52]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][53]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][54]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][55]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][56]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][57]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][58]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][59]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][60]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][61]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][62]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][63]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][64]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][65]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][66]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][67]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][68]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][69]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][70]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][71]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][72]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][73]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][74]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][75]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][76]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][77]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][78]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][79]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][80]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][81]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][82]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][83]."
".$graph_stats2[$d][0]."".$graph_stats2[$d][84]."
"._QXZ("TOTAL").": $current_graph_total
TOTAL:".$totals2[1]."
TOTAL:".$totals2[2]."
TOTAL:".$totals2[3]."
TOTAL:".$totals2[4]."
TOTAL:".$totals2[5]."
TOTAL:".$totals2[6]."
TOTAL:".$totals2[7]."
TOTAL:".$totals2[8]."
TOTAL:".$totals2[9]."
TOTAL:".$totals2[10]."
TOTAL:".$totals2[11]."
TOTAL:".$totals2[12]."
TOTAL:".$totals2[13]."
TOTAL:".$totals2[14]."
TOTAL:".$totals2[15]."
TOTAL:".$totals2[16]."
TOTAL:".$totals2[17]."
TOTAL:".$totals2[18]."
TOTAL:".$totals2[19]."
TOTAL:".$totals2[20]."
TOTAL:".$totals2[21]."
TOTAL:".$totals2[22]."
TOTAL:".$totals2[23]."
TOTAL:".$totals2[24]."
TOTAL:".$totals2[25]."
TOTAL:".$totals2[26]."
TOTAL:".$totals2[27]."
TOTAL:".$totals2[28]."
TOTAL:".$totals2[29]."
TOTAL:".$totals2[30]."
TOTAL:".$totals2[31]."
TOTAL:".$totals2[32]."
TOTAL:".$totals2[33]."
TOTAL:".$totals2[34]."
TOTAL:".$totals2[35]."
TOTAL:".$totals2[36]."
TOTAL:".$totals2[37]."
TOTAL:".$totals2[38]."
TOTAL:".$totals2[39]."
TOTAL:".$totals2[40]."
TOTAL:".$totals2[41]."
TOTAL:".$totals2[42]."
TOTAL:".$totals2[43]."
TOTAL:".$totals2[44]."
TOTAL:".$totals2[45]."
TOTAL:".$totals2[46]."
TOTAL:".$totals2[47]."
TOTAL:".$totals2[48]."
TOTAL:".$totals2[49]."
TOTAL:".$totals2[50]."
TOTAL:".$totals2[51]."
TOTAL:".$totals2[52]."
TOTAL:".$totals2[53]."
TOTAL:".$totals2[54]."
TOTAL:".$totals2[55]."
TOTAL:".$totals2[56]."
TOTAL:".$totals2[57]."
TOTAL:".$totals2[58]."
TOTAL:".$totals2[59]."
TOTAL:".$totals2[60]."
TOTAL:".$totals2[61]."
TOTAL:".$totals2[62]."
TOTAL:".$totals2[63]."
TOTAL:".$totals2[64]."
TOTAL:".$totals2[65]."
TOTAL:".$totals2[66]."
TOTAL:".$totals2[67]."
TOTAL:".$totals2[68]."
TOTAL:".$totals2[69]."
TOTAL:".$totals2[70]."
TOTAL:".$totals2[71]."
TOTAL:".$totals2[72]."
TOTAL:".$totals2[73]."
TOTAL:".$totals2[74]."
TOTAL:".$totals2[75]."
TOTAL:".$totals2[76]."
TOTAL:".$totals2[77]."
TOTAL:".$totals2[78]."
TOTAL:".$totals2[79]."
TOTAL:".$totals2[80]."
TOTAL:".$totals2[81]."
TOTAL:".$totals2[82]."
TOTAL:".$totals2[83]."
TOTAL:".$totals2[84]."
"._QXZ("TOTAL").": $current_graph_total
\"\"".$graph_stats[$d][0]."
"._QXZ("TOTAL").":".trim($TOTALleads)."
\n";
-	$GRAPH.="

"; + + $graph_count=count($graph_array); + $graph_title=_QXZ("LIST ID SUMMARY 1"); + include("graphcanvas.inc"); + $GRAPH.=$graphCanvas; if ($report_display_type=="HTML") @@ -2462,9 +2157,9 @@ else $JS_text.="\n"; echo $HEADER; - echo $JS_text; require("admin_header.php"); echo $MAIN; + echo $JS_text; } diff --git a/agc_2-X/trunk/www/vicidial/AST_OUTBOUNDsummary_interval.php b/agc_2-X/trunk/www/vicidial/AST_OUTBOUNDsummary_interval.php index c867e36d..047f4bcb 100644 --- a/agc_2-X/trunk/www/vicidial/AST_OUTBOUNDsummary_interval.php +++ b/agc_2-X/trunk/www/vicidial/AST_OUTBOUNDsummary_interval.php @@ -26,6 +26,7 @@ # 150516-1305 - Fixed Javascript element problem, Issue #857 # 151125-1632 - Added search archive option # 160227-1136 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -74,6 +75,7 @@ if (strlen($include_rollover)<2) {$include_rollover='NO';} $report_name = 'Outbound Summary Interval Report'; $db_source = 'M'; + $JS_text="\n"; $HEADER.="\n"; $HEADER.="\n"; +require("chart_button.php"); +$HEADER.="\n"; +$HEADER.="\n"; $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; @@ -783,19 +788,7 @@ else $max_login_time=1; $max_pause_time=1; - $GRAPH="

"; - $GRAPH.=""; - $GRAPH.="
"._QXZ("CALLS").""._QXZ("SYSTEM RELEASE CALLS").""._QXZ("AGENT RELEASE CALLS").""._QXZ("SALE CALLS").""._QXZ("DNC CALLS").""._QXZ("NO ANSWER PERCENT").""._QXZ("DROP PERCENT").""._QXZ("AGENT LOGIN TIME").""._QXZ("AGENT PAUSE TIME")."

 


"; - $graph_header=""; - $CALLS_graph=$graph_header.""; - $SYSTEMRELEASE_graph=$graph_header.""; - $AGENTRELEASE_graph=$graph_header.""; - $SALES_graph=$graph_header.""; - $DNCS_graph=$graph_header.""; - $NAS_graph=$graph_header.""; - $DROPS_graph=$graph_header.""; - $LOGINTIME_graph=$graph_header.""; - $PAUSETIME_graph=$graph_header.""; + ########################### $i=0; @@ -1290,31 +1283,6 @@ else $CSV_subreports.="\""._QXZ("INTERVAL")."\",\""._QXZ("TOTAL CALLS")."\",\""._QXZ("SYSTEM RELEASE CALLS")."\",\""._QXZ("AGENT RELEASE CALLS")."\",\""._QXZ("SALE CALLS")."\",\""._QXZ("DNC CALLS")."\",\""._QXZ("NO ANSWER PERCENT")."\",\""._QXZ("DROP PERCENT")."\",\""._QXZ("AGENT LOGIN TIME (H:M:S)")."\",\""._QXZ("AGENT PAUSE TIME(H:M:S)")."\"\n"; ######## GRAPHING ######### - $SUBmax_calls=1; - $SUBmax_system_release=1; - $SUBmax_agent_release=1; - $SUBmax_sales=1; - $SUBmax_dncs=1; - $SUBmax_nas=1; - $SUBmax_drops=1; - $SUBmax_login_time=1; - $SUBmax_pause_time=1; - $SUBgraph_stats=""; - $SUBrpt_campaign=$group[$i]; - - $SUBGRAPH="

"._QXZ("MULTI-CAMPAIGN BREAKDOWN")."
"._QXZ("CAMPAIGNS").""._QXZ("TOTAL CALLS")."
"._QXZ("SYSTEM RELEASE CALLS")."
"._QXZ("AGENT RELEASE CALLS")."
"._QXZ("SALE CALLS")."
"._QXZ("DNC CALLS")."
"._QXZ("NO ANSWER PERCENT")."
"._QXZ("DROP PERCENT")."
"._QXZ("AGENT LOGIN TIME (H:M:S)")."
"._QXZ("AGENT PAUSE TIME (H:M:S)")."
"; - $SUBGRAPH.=""; - $SUBGRAPH.="
"._QXZ("CALLS").""._QXZ("SYSTEM RELEASE CALLS").""._QXZ("AGENT RELEASE CALLS").""._QXZ("SALE CALLS").""._QXZ("DNC CALLS").""._QXZ("NO ANSWER PERCENT").""._QXZ("DROP PERCENT").""._QXZ("AGENT LOGIN TIME").""._QXZ("AGENT PAUSE TIME")."

 


"; - $SUBgraph_header=""; - $SUBCALLS_graph=$SUBgraph_header.""; - $SUBSYSTEMRELEASE_graph=$SUBgraph_header.""; - $SUBAGENTRELEASE_graph=$SUBgraph_header.""; - $SUBSALES_graph=$SUBgraph_header.""; - $SUBDNCS_graph=$SUBgraph_header.""; - $SUBNAS_graph=$SUBgraph_header.""; - $SUBDROPS_graph=$SUBgraph_header.""; - $SUBLOGINTIME_graph=$SUBgraph_header.""; - $SUBPAUSETIME_graph=$SUBgraph_header.""; ########################### $h=0; $z=0; @@ -1456,53 +1424,90 @@ else $SUB_ASCII_text .= "| "._QXZ("TOTALS",19)." | $hTOTcalls_count | $hTOTsystem_count | $hTOTagent_count | $hTOTptp_count | $hTOTrtp_count | $hTOTna_percent%| $hTOTdrop_percent%| $hTOTagent_sec | $hTOTpause_sec |\n"; $SUB_ASCII_text .= "+---------------------+--------+--------+--------+--------+--------+--------+--------+------------+------------+\n"; $CSV_subreports.="\""._QXZ("TOTALS")."\",\"$hTOTcalls_count\",\"$hTOTsystem_count\",\"$hTOTagent_count\",\"$hTOTptp_count\",\"$hTOTrtp_count\",\"$hTOTna_percent%\",\"$hTOTdrop_percent%\",\"$hTOTagent_sec\",\"$hTOTpause_sec\"\n"; + + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + + $graph_array=array("OSI_CALLSdata$group[$i]|1|CALLS|integer|", "OSI_SYSTEMRELEASEdata$group[$i]|2|SYSTEM RELEASE CALLS|integer|", "OSI_AGENTRELEASEdata$group[$i]|3|AGENT RELEASE CALLS|integer|", "OSI_SALECALLSdata$group[$i]|4|SALE CALLS|integer|", "OSI_DNCCALLSdata$group[$i]|5|DNC CALLS|integer|", "OSI_NOANSWERPERCENTdata$group[$i]|6|NO ANSWER PERCENT|percent|", "OSI_DROPPERCENTdata$group[$i]|7|DROP PERCENT|percent|", "OSI_AGENTLOGINdata$group[$i]|8|AGENT LOGIN TIME|time|", "OSI_AGENTPAUSEdata$group[$i]|9|AGENT PAUSE TIME|time|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title="$group[$i] - $group_cname[$i] "._QXZ("INTERVAL BREAKDOWN"); + include("graphcanvas.inc"); + $SUB_HTML_text.=$graphCanvas; + $i++; - - for ($d=0; $d"; - $SUBSYSTEMRELEASE_graph.=" "; - $SUBAGENTRELEASE_graph.=" "; - $SUBSALES_graph.=" "; - $SUBDNCS_graph.=" "; - $SUBNAS_graph.=" "; - $SUBDROPS_graph.=" "; - $SUBLOGINTIME_graph.=" "; - $SUBPAUSETIME_graph.=" "; - } - $SUBCALLS_graph.="
$SUBrpt_campaign - $group_cname[$i] "._QXZ("INTERVAL BREAKDOWN").":
"._QXZ("INTERVAL").""._QXZ("TOTAL CALLS")."
"._QXZ("SYSTEM RELEASE CALLS")."
"._QXZ("AGENT RELEASE CALLS")."
"._QXZ("SALE CALLS")."
"._QXZ("DNC CALLS")."
"._QXZ("NO ANSWER PERCENT")."
"._QXZ("DROP PERCENT")."
"._QXZ("AGENT LOGIN TIME (H:M:S)")."
"._QXZ("AGENT PAUSE TIME (H:M:S)")."
"._QXZ("TOTAL").": $current_graph_total
".$SUBgraph_stats[$d][1]."
".$SUBgraph_stats[$d][0]."".$SUBgraph_stats[$d][2]."
".$SUBgraph_stats[$d][0]."".$SUBgraph_stats[$d][3]."
".$SUBgraph_stats[$d][0]."".$SUBgraph_stats[$d][4]."
".$SUBgraph_stats[$d][0]."".$SUBgraph_stats[$d][5]."
".$SUBgraph_stats[$d][0]."".$SUBgraph_stats[$d][6]."%
".$SUBgraph_stats[$d][0]."".$SUBgraph_stats[$d][7]."%
".$SUBgraph_stats[$d][0]."".sec_convert($SUBgraph_stats[$d][8], 'H')."
".$SUBgraph_stats[$d][0]."".sec_convert($SUBgraph_stats[$d][9], 'H')."
"._QXZ("TOTAL").":".trim($hTOTcalls_count)."
"; - $SUBSYSTEMRELEASE_graph.=""._QXZ("TOTAL").":".trim($hTOTsystem_count).""; - $SUBAGENTRELEASE_graph.=""._QXZ("TOTAL").":".trim($hTOTagent_count).""; - $SUBSALES_graph.=""._QXZ("TOTAL").":".trim($hTOTptp_count).""; - $SUBDNCS_graph.=""._QXZ("TOTAL").":".trim($hTOTrtp_count).""; - $SUBNAS_graph.=""._QXZ("TOTAL").":".trim($hTOTna_percent)."%"; - $SUBDROPS_graph.=""._QXZ("TOTAL").":".trim($hTOTdrop_percent)."%"; - $SUBLOGINTIME_graph.=""._QXZ("TOTAL").":".trim($hTOTagent_sec).""; - $SUBPAUSETIME_graph.=""._QXZ("TOTAL").":".trim($hTOTpause_sec).""; - $JS_onload.="\tDraw".$SUBrpt_campaign."CampaignGraph('CALLS', '1');\n"; - $JS_text.="function Draw".$SUBrpt_campaign."CampaignGraph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$SUBCALLS_graph\";\n"; - $JS_text.=" var SYSTEMRELEASE_graph=\"$SUBSYSTEMRELEASE_graph\";\n"; - $JS_text.=" var AGENTRELEASE_graph=\"$SUBAGENTRELEASE_graph\";\n"; - $JS_text.=" var SALES_graph=\"$SUBSALES_graph\";\n"; - $JS_text.=" var DNCS_graph=\"$SUBDNCS_graph\";\n"; - $JS_text.=" var NAS_graph=\"$SUBNAS_graph\";\n"; - $JS_text.=" var DROPS_graph=\"$SUBDROPS_graph\";\n"; - $JS_text.=" var LOGINTIME_graph=\"$SUBLOGINTIME_graph\";\n"; - $JS_text.=" var PAUSETIME_graph=\"$SUBPAUSETIME_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=9; i++) {\n"; - $JS_text.=" var cellID=\"campbreakdown".$SUBrpt_campaign."\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"campbreakdown".$SUBrpt_campaign."\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('campaign_breakdown_".$SUBrpt_campaign."').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $SUB_HTML_text.=$SUBGRAPH; - } - + } $rawTOTtalk_sec = $TOTtalk_sec; $rawTOTtalk_min = round(MathZDC($rawTOTtalk_sec, 60)); @@ -1574,49 +1579,87 @@ else exit; } - for ($d=0; $d".$graph_stats[$d][1].""; - $SYSTEMRELEASE_graph.=" ".$graph_stats[$d][0]."".$graph_stats[$d][2].""; - $AGENTRELEASE_graph.=" ".$graph_stats[$d][0]."".$graph_stats[$d][3].""; - $SALES_graph.=" ".$graph_stats[$d][0]."".$graph_stats[$d][4].""; - $DNCS_graph.=" ".$graph_stats[$d][0]."".$graph_stats[$d][5].""; - $NAS_graph.=" ".$graph_stats[$d][0]."".$graph_stats[$d][6]."%"; - $DROPS_graph.=" ".$graph_stats[$d][0]."".$graph_stats[$d][7]."%"; - $LOGINTIME_graph.=" ".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][8], 'H').""; - $PAUSETIME_graph.=" ".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][9], 'H').""; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + + $graph_array=array("OSI_CALLSdata|1|CALLS|integer|", "OSI_SYSTEMRELEASEdata|2|SYSTEM RELEASE CALLS|integer|", "OSI_AGENTRELEASEdata|3|AGENT RELEASE CALLS|integer|", "OSI_SALECALLSdata|4|SALE CALLS|integer|", "OSI_DNCCALLSdata|5|DNC CALLS|integer|", "OSI_NOANSWERPERCENTdata|6|NO ANSWER PERCENT|percent|", "OSI_DROPPERCENTdata|7|DROP PERCENT|percent|", "OSI_AGENTLOGINdata|8|AGENT LOGIN TIME|time|", "OSI_AGENTPAUSEdata|9|AGENT PAUSE TIME|time|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $CALLS_graph.=""._QXZ("TOTAL").":".trim($TOTcalls_count).""; - $SYSTEMRELEASE_graph.=""._QXZ("TOTAL").":".trim($TOTsystem_count).""; - $AGENTRELEASE_graph.=""._QXZ("TOTAL").":".trim($TOTagent_count).""; - $SALES_graph.=""._QXZ("TOTAL").":".trim($TOTptp_count).""; - $DNCS_graph.=""._QXZ("TOTAL").":".trim($TOTrtp_count).""; - $NAS_graph.=""._QXZ("TOTAL").":".trim($TOTna_percent)."%"; - $DROPS_graph.=""._QXZ("TOTAL").":".trim($TOTdrop_percent)."%"; - $LOGINTIME_graph.=""._QXZ("TOTAL").":".trim($TOTagent_sec).""; - $PAUSETIME_graph.=""._QXZ("TOTAL").":".trim($TOTpause_sec).""; - $JS_onload.="\tDrawMultiCampaignGraph('CALLS', '1');\n"; - $JS_text.="function DrawMultiCampaignGraph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$CALLS_graph\";\n"; - $JS_text.=" var SYSTEMRELEASE_graph=\"$SYSTEMRELEASE_graph\";\n"; - $JS_text.=" var AGENTRELEASE_graph=\"$AGENTRELEASE_graph\";\n"; - $JS_text.=" var SALES_graph=\"$SALES_graph\";\n"; - $JS_text.=" var DNCS_graph=\"$DNCS_graph\";\n"; - $JS_text.=" var NAS_graph=\"$NAS_graph\";\n"; - $JS_text.=" var DROPS_graph=\"$DROPS_graph\";\n"; - $JS_text.=" var LOGINTIME_graph=\"$LOGINTIME_graph\";\n"; - $JS_text.=" var PAUSETIME_graph=\"$PAUSETIME_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=9; i++) {\n"; - $JS_text.=" var cellID=\"campbreakdown\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"campbreakdown\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('multi_campaign_breakdown').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $GRAPH_text.=$GRAPH; + + $graph_count=count($graph_array); + $graph_title=_QXZ("MULTI-CAMPAIGN BREAKDOWN"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas; + if ($file_download>0) { # $CSV_report=fopen("AST_OUTBOUNDsummary_interval.csv", "w"); @@ -1676,10 +1719,10 @@ else } echo "$HEADER"; - echo $JS_text; require("admin_header.php"); echo "$MAIN"; echo "$SUBoutput"; + echo $JS_text; $ENDtime = date("U"); $RUNtime = ($ENDtime - $STARTtime); echo "\n\n"._QXZ("Run Time").": $RUNtime "._QXZ("seconds")."|$db_source\n"; diff --git a/agc_2-X/trunk/www/vicidial/AST_VDADstats.php b/agc_2-X/trunk/www/vicidial/AST_VDADstats.php index c32e7219..3ab47837 100644 --- a/agc_2-X/trunk/www/vicidial/AST_VDADstats.php +++ b/agc_2-X/trunk/www/vicidial/AST_VDADstats.php @@ -48,6 +48,7 @@ # 151125-1615 - Added search archive option # 160227-1101 - Uniform form format # 160515-1412 - Added UK OFCOM feature +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -523,6 +524,9 @@ $NWE = "')\">\"HELP\"\n"; echo "\n"; echo "\n"; +require("chart_button.php"); +echo "\n"; +echo "\n"; echo "\n"; echo "\n"; echo "\n"; + require("chart_button.php"); + echo "\n"; + echo "\n"; echo "\n"; echo ""._QXZ("$report_name")."\n"; @@ -447,8 +451,6 @@ else { $ASCII_text.=_QXZ("Agent Days Status Report",24).": $user $NOW_TIME ($db_source)\n"; $ASCII_text.=_QXZ("Time range").": $query_date_BEGIN "._QXZ("to")." $query_date_END\n\n"; - $GRAPH_text.=_QXZ("Agent Days Status Report",24).": $user $NOW_TIME ($db_source)\n"; - $GRAPH_text.=_QXZ("Time range").": $query_date_BEGIN "._QXZ("to")." $query_date_END\n\n"; } else { @@ -512,7 +514,6 @@ else $Sstatus=$statusesARY[$i]; $SstatusTXT=$Sstatus; if ($Sstatus=="") {$SstatusTXT="(blank)";} - $GRAPH2.="
$SstatusTXT"; } } @@ -530,12 +531,6 @@ else $max_calls=1; $max_cicalls=1; $max_dncci=1; - $GRAPH="

"; - $GRAPH2=""; - $graph_header="
"._QXZ("CALLS").""._QXZ("CI/CALLS").""._QXZ("DNC/CI")."
"; - $CALLS_graph=$graph_header.""; - $CICALLS_graph=$graph_header.""; - $DNCCI_graph=$graph_header.""; while ($m < $k) { @@ -760,59 +755,94 @@ else $Sstatus=$statusesARY[$e]; $SstatusTXT=$Sstatus; if ($Sstatus=="") {$SstatusTXT="(blank)";} - $GRAPH2.=""; } - - for ($d=0; $d"; - $CICALLS_graph.=" "; - $DNCCI_graph.=" "; - for ($e=0; $e"; + $graph_totals_rawdata[$q]=$current_graph_total; + switch($dataset_type) { + case "time": + $graph_totals_array[$q]=" \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; } + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } + + $graph_count=count($graph_array); + $graph_title=_QXZ("LEAD STATS BREAKDOWN"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas; - $CALLS_graph.="
"._QXZ("LEAD STATS BREAKDOWN")."
"._QXZ("STATUS").""._QXZ("CALLS")."
"._QXZ("CI CALLS")."
"._QXZ("DNC/CI")."%
$SstatusTXT".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".$graph_stats[$d][2]."
".$graph_stats[$d][0]."".$graph_stats[$d][3]."%
".$graph_stats[$d][($e+4)]."
"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." "._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTcalls)."
"; - $CICALLS_graph.=""._QXZ("TOTAL").":".trim($CIScountTOT).""; - $DNCCI_graph.=""._QXZ("TOTAL").":".trim($DNCcountPCT)."%"; - for ($e=0; $e".trim($$total_var).""; - } - $JS_onload.="\tDrawGraph('CALLS', '1');\n"; - $JS_text.="function DrawGraph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$CALLS_graph\";\n"; - $JS_text.=" var CICALLS_graph=\"$CICALLS_graph\";\n"; - $JS_text.=" var DNCCI_graph=\"$DNCCI_graph\";\n"; - - for ($e=0; $e
 


"; - - $GRAPH_text.=$GRAPH.$GRAPH2.$GRAPH3; } else @@ -957,8 +987,8 @@ echo ""; if ($report_display_type=="HTML") { - echo $JS_text; echo $GRAPH_text; + echo $JS_text; } else { diff --git a/agc_2-X/trunk/www/vicidial/AST_agent_performance_detail.php b/agc_2-X/trunk/www/vicidial/AST_agent_performance_detail.php index 51772866..4c4c8725 100644 --- a/agc_2-X/trunk/www/vicidial/AST_agent_performance_detail.php +++ b/agc_2-X/trunk/www/vicidial/AST_agent_performance_detail.php @@ -55,6 +55,7 @@ # 151229-2015 - Added feature to break down agent stats by day # 160121-2212 - Added report title header, default report format, cleaned up formatting # 160503-2137 - Bug fix and inclusion of null sub_statuses in counts for "PAUSE CODE BREAKDOWN" section +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -479,6 +480,9 @@ $HTML_head.=" \n"; $HTML_head.="\n"; $HTML_head.="\n"; $HTML_head.="\n"; +require("chart_button.php"); +$HTML_head.="\n"; +$HTML_head.="\n"; $HTML_head.="\n"; $HTML_head.=""._QXZ("$report_name")."\n"; @@ -705,23 +709,6 @@ $max_dead=1; $max_deadavg=1; $max_customer=1; $max_customeravg=1; -$GRAPH="

"; -$GRAPH2=""; -$graph_header="
"._QXZ("CALLS").""._QXZ("TIME").""._QXZ("PAUSE").""._QXZ("PAUSE AVG").""._QXZ("WAIT").""._QXZ("WAIT AVG").""._QXZ("TALK").""._QXZ("TALK AVG").""._QXZ("DISPO").""._QXZ("DISPO AVG").""._QXZ("DEAD").""._QXZ("DEAD AVG").""._QXZ("CUST").""._QXZ("CUST AVG")."
"; -$CALLS_graph=$graph_header.""; -$TIME_graph=$graph_header.""; -$PAUSE_graph=$graph_header.""; -$PAUSEAVG_graph=$graph_header.""; -$WAIT_graph=$graph_header.""; -$WAITAVG_graph=$graph_header.""; -$TALK_graph=$graph_header.""; -$TALKAVG_graph=$graph_header.""; -$DISPO_graph=$graph_header.""; -$DISPOAVG_graph=$graph_header.""; -$DEAD_graph=$graph_header.""; -$DEADAVG_graph=$graph_header.""; -$CUST_graph=$graph_header.""; -$CUSTAVG_graph=$graph_header.""; if ($show_defunct_users=="checked") { @@ -1494,98 +1481,96 @@ if ($show_percentages) { $ASCII_text.="+-----------------+----------+----------------------+----------------------+".$BBD_header."--------+-----------+----------+--------+----------+--------+----------+--------+----------+--------+----------+--------+----------+--------+$statusesHEAD\n"; } +# USE THIS FOR COMBINED graphs, use pipe-delimited array elements, dataset_name|index|link_name|graph_override +# You have to hard code the graph name in where it is overridden and mind the data indices. No other way to do it. +$multigraph_text=""; +$graph_id++; +$graph_array=array("APD_CALLSdata|1|CALLS|integer|", "APD_TIMEdata|2|TIME|time|", "APD_PAUSEdata|3|PAUSE|time|", "APD_PAUSEdata|4|PAUSE AVG|time|", "APD_WAITdata|5|WAIT|time|", "APD_WAITdata|6|WAIT AVG|time|", "APD_TALKdata|7|TALK|time|", "APD_TALKdata|8|TALK AVG|time|", "APD_DISPOdata|9|DISPO|time|", "APD_DISPOdata|10|DISPO AVG|time|", "APD_DEADdata|11|DEAD|time|", "APD_DEADdata|12|DEAD AVG|time|", "APD_CUSTdata|13|CUST|time|", "APD_CUSTdata|14|CUST AVG|time|"); + for ($e=0; $e$SstatusTXT"; + array_push($graph_array, "APD_SUBSTATUS".$e."data|".($e+15)."|".$SstatusTXT."|integer|"); } -for ($d=0; $d"; - $TIME_graph.=" "; - $PAUSE_graph.=" "; - $PAUSEAVG_graph.=" "; - $WAIT_graph.=" "; - $WAITAVG_graph.=" "; - $TALK_graph.=" "; - $TALKAVG_graph.=" "; - $DISPO_graph.=" "; - $DISPOAVG_graph.=" "; - $DEAD_graph.=" "; - $DEADAVG_graph.=" "; - $CUST_graph.=" "; - $CUSTAVG_graph.=" "; +$default_graph="bar"; # Graph that is initally displayed when page loads +include("graph_color_schemas.inc"); - for ($e=0; $e\n"; - - $$varname.=" "; +$graph_totals_array=array(); +$graph_totals_rawdata=array(); +for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; } -} - -$CALLS_graph.="
"._QXZ("CALL STATS BREAKDOWN").": ("._QXZ("Statistics related to handling of calls only").")
"._QXZ("USER").""._QXZ("CALLS")."
"._QXZ("TIME")."
"._QXZ("PAUSE")."
"._QXZ("PAUSE AVG")."
"._QXZ("WAIT")."
"._QXZ("WAIT AVG")."
"._QXZ("TALK")."
"._QXZ("TALK AVG")."
"._QXZ("DISPO")."
"._QXZ("DISPO AVG")."
"._QXZ("DEAD")."
"._QXZ("DEAD AVG")."
"._QXZ("CUST")."
"._QXZ("CUST AVG")."
".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][2], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][3], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][4], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][5], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][6], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][7], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][8], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][9], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][10], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][11], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][12], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][13], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][14], $TIME_HF_agentperfdetail)."
".$graph_stats[$d][0]."".$graph_stats[$d][($e+15)]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($TOTcalls)."
"; -$TIME_graph.=""._QXZ("TOTAL").":".trim($TOTtime_MS).""; -$PAUSE_graph.=""._QXZ("TOTAL").":".trim($TOTtotPAUSE_MS).""; -$PAUSEAVG_graph.=""._QXZ("TOTAL").":".trim($TOTavgPAUSE_MS).""; -$WAIT_graph.=""._QXZ("TOTAL").":".trim($TOTtotWAIT_MS).""; -$WAITAVG_graph.=""._QXZ("TOTAL").":".trim($TOTavgWAIT_MS).""; -$TALK_graph.=""._QXZ("TOTAL").":".trim($TOTtotTALK_MS).""; -$TALKAVG_graph.=""._QXZ("TOTAL").":".trim($TOTavgTALK_MS).""; -$DISPO_graph.=""._QXZ("TOTAL").":".trim($TOTtotDISPO_MS).""; -$DISPOAVG_graph.=""._QXZ("TOTAL").":".trim($TOTavgDISPO_MS).""; -$DEAD_graph.=""._QXZ("TOTAL").":".trim($TOTtotDEAD_MS).""; -$DEADAVG_graph.=""._QXZ("TOTAL").":".trim($TOTavgDEAD_MS).""; -$CUST_graph.=""._QXZ("TOTAL").":".trim($TOTtotCUSTOMER_MS).""; -$CUSTAVG_graph.=""._QXZ("TOTAL").":".trim($TOTavgCUSTOMER_MS).""; -for ($e=0; $e".trim($$total_var).""; + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } -$JS_onload.="\tDrawGraph('CALLS', '1');\n"; -$JS_text.="function DrawGraph(graph, th_id) {\n"; -$JS_text.=" var graph_CALLS=\"$CALLS_graph\";\n"; -$JS_text.=" var graph_TIME=\"$TIME_graph\";\n"; -$JS_text.=" var graph_PAUSE=\"$PAUSE_graph\";\n"; -$JS_text.=" var graph_PAUSEAVG=\"$PAUSEAVG_graph\";\n"; -$JS_text.=" var graph_WAIT=\"$WAIT_graph\";\n"; -$JS_text.=" var graph_WAITAVG=\"$WAITAVG_graph\";\n"; -$JS_text.=" var graph_TALK=\"$TALK_graph\";\n"; -$JS_text.=" var graph_TALKAVG=\"$TALKAVG_graph\";\n"; -$JS_text.=" var graph_DISPO=\"$DISPO_graph\";\n"; -$JS_text.=" var graph_DISPOAVG=\"$DISPOAVG_graph\";\n"; -$JS_text.=" var graph_DEAD=\"$DEAD_graph\";\n"; -$JS_text.=" var graph_DEADAVG=\"$DEADAVG_graph\";\n"; -$JS_text.=" var graph_CUST=\"$CUST_graph\";\n"; -$JS_text.=" var graph_CUSTAVG=\"$CUSTAVG_graph\";\n"; -for ($e=0; $e
 


"; +$graph_count=count($graph_array); +$graph_title=_QXZ("CALL STATS BREAKDOWN: (Statistics related to handling of calls only)"); +include("graphcanvas.inc"); +$GRAPH.=$graphCanvas; $GRAPH_text.=$JS_text.$GRAPH.$GRAPH2.$GRAPH3; @@ -1674,12 +1659,6 @@ $graph_stats=array(); $max_total=1; $max_nonpause=1; $max_pause=1; -$GRAPH="

"; -$GRAPH2=""; -$graph_header="
"._QXZ("TOTAL").""._QXZ("NONPAUSE").""._QXZ("PAUSE")."
"; -$TOTAL_graph=$graph_header.""; -$NONPAUSE_graph=$graph_header.""; -$PAUSE_graph=$graph_header.""; $sub_status_stmt="SELECT distinct if(sub_status is null, '*', sub_status) as all_subs from ".$agent_log_table." where event_time <= '$query_date_END' and event_time >= '$query_date_BEGIN' and pause_sec >= 0 and pause_sec < 65000 $group_SQL $user_agent_log_SQL order by all_subs asc limit 10000000;"; if ($DB) {$ASCII_text.="$sub_status_stmt\n";} @@ -1986,67 +1965,96 @@ $ASCII_text.="+-----------------+----------+----------------------+------------- $ASCII_text.="| "._QXZ("TOTALS",33)." "._QXZ("AGENTS",32,"r").":$TOT_AGENTS |$TOTtotTOTAL_MS|$TOTtotNONPAUSE_MS|$TOTtotPAUSE_MS| |$SUMstatusesHTML\n"; $ASCII_text.="+-----------------+----------+----------------------+----------------------+------------+----------+----------+ +$sub_statusesHEAD\n"; +# USE THIS FOR COMBINED graphs, use pipe-delimited array elements, dataset_name|index|link_name|graph_override +# You have to hard code the graph name in where it is overridden and mind the data indices. No other way to do it. +$multigraph_text=""; +$graph_id++; +$graph_array=array("APD_TOTALdata|1|TOTAL|time|", "APD_NONPAUSEdata|2|NONPAUSE|time|", "APD_PAUSEdata|3|PAUSE|time|"); + for ($e=0; $e$SstatusTXT"; + array_push($graph_array, "APDP_SUBSTATUS".$e."data|".($e+4)."|".$sub_statusesARY[$e]."|time|"); } -for ($d=0; $d"; - $NONPAUSE_graph.=" "; - $PAUSE_graph.=" "; +$default_graph="bar"; # Graph that is initally displayed when page loads +include("graph_color_schemas.inc"); - for ($e=0; $e"; + $graph_totals_rawdata[$q]=$current_graph_total; + switch($dataset_type) { + case "time": + $graph_totals_array[$q]=" \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } -$TOTAL_graph.="
"._QXZ("PAUSE CODE BREAKDOWN")."
"._QXZ("STATUS").""._QXZ("TOTAL")."
"._QXZ("NONPAUSE")."
"._QXZ("PAUSE")."
".sec_convert($graph_stats[$d][1], $TIME_H_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][2], $TIME_H_agentperfdetail)."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][3], $TIME_H_agentperfdetail)."
".sec_convert($graph_stats[$d][($e+4)], $TIME_H_agentperfdetail)."
"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." "._QXZ("TOTAL").": $current_graph_total
"._QXZ("LOGIN TIME").":".trim($TOTtotTOTAL_MS)."
"; -$NONPAUSE_graph.=""._QXZ("LOGIN TIME").":".trim($TOTtotNONPAUSE_MS).""; -$PAUSE_graph.=""._QXZ("LOGIN TIME").":".trim($TOTtotPAUSE_MS)."%"; -for ($e=0; $e".trim(sec_convert($$total_var, $TIME_H_agentperfdetail)).""; -} -$JS_onload.="\tDrawPauseGraph('TOTAL', '1');\n"; -$JS_text="\n"; -$GRAPH3="
 


"; - -$GRAPH_text.=$JS_text.$GRAPH.$GRAPH2.$GRAPH3.$max; - $CSV_total=preg_replace('/\s/', '', "\"\",\"\",\""._QXZ("TOTALS")."\",\""._QXZ("AGENTS").":$TOT_AGENTS\",\"$TOTtotTOTAL_MS\",\"$TOTtotNONPAUSE_MS\",\"$TOTtotPAUSE_MS\",$CSVSUMstatuses"); @@ -2097,7 +2105,7 @@ fwrite($CSV_report, $CSV_total); if ($report_display_type=="HTML") { - $HTML_text.=$GRAPH_text; + $HTML_text.=$GRAPH.$JS_text; } else { diff --git a/agc_2-X/trunk/www/vicidial/AST_agent_status_detail.php b/agc_2-X/trunk/www/vicidial/AST_agent_status_detail.php index 7d62cff1..5e292f47 100644 --- a/agc_2-X/trunk/www/vicidial/AST_agent_status_detail.php +++ b/agc_2-X/trunk/www/vicidial/AST_agent_status_detail.php @@ -32,6 +32,7 @@ # 160301-2051 - Expanded full name to 25 characters on text display # 160310-2115 - Fixed bug in HTML display # 160330-0648 - Fixed issue with names and non-latin setting +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -74,6 +75,7 @@ if ($search_archived_data=="checked") {$agent_log_table="vicidial_agent_log_arch $report_name = 'Agent Status Detail'; $db_source = 'M'; + $JS_text="\n"; echo "\n"; echo "\n"; + require("chart_button.php"); + echo "\n"; + echo "\n"; echo "\n"; echo "$report_name\n"; @@ -636,13 +641,6 @@ else $ASCII_text.="| USER NAME | ID | CALLS | CIcalls| DNC/CI%|$statusesHTML\n"; $ASCII_text.="+---------------------------+----------+--------+--------+--------+$statusesHEAD\n"; - for ($i=0; $i$SstatusTXT"; - } - } else { @@ -659,12 +657,6 @@ else $max_calls=1; $max_cicalls=1; $max_dncci=1; - $GRAPH.="

"; - $GRAPH2=""; - $graph_header="
CALLSCI/CALLSDNC/CI
"; - $CALLS_graph=$graph_header.""; - $CICALLS_graph=$graph_header.""; - $DNCCI_graph=$graph_header.""; while ($m < $k) { @@ -899,64 +891,95 @@ else $ASCII_text.="\n\n"; + # USE THIS FOR COMBINED graphs, use pipe-delimited array elements, dataset_name|index|link_name|graph_override + # You have to hard code the graph name in where it is overridden and mind the data indices. No other way to do it. + $multigraph_text=""; + $graph_id++; + $graph_array=array("ASD_CALLSdata|1|CALLS|integer|", "ASD_CICALLSdata|2|CI/CALLS|integer|", "ASD_DNCCIdata|3|DNC/CI|percent|"); + for ($e=0; $e$SstatusTXT"; + array_push($graph_array, "ASD_SUBSTATUS".$e."data|".($e+4)."|".$SstatusTXT."|integer|"); } - for ($d=0; $d"; - $CICALLS_graph.=" "; - $DNCCI_graph.=" "; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); - for ($e=0; $e\n"; + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"; + $graph_totals_rawdata[$q]=$current_graph_total; + switch($dataset_type) { + case "time": + $graph_totals_array[$q]=" \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; } - } - - $CALLS_graph.="
CALL STATS BREAKDOWN
STATUSCALLS
CI CALLS
DNC/CI%
".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".$graph_stats[$d][2]."
".$graph_stats[$d][0]."".$graph_stats[$d][3]."%
".$graph_stats[$d][($e+4)]."
"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." "._QXZ("TOTAL").": $current_graph_total
TOTAL:".trim($TOTcalls)."
"; - $CICALLS_graph.="TOTAL:".trim($CIScountTOT).""; - $DNCCI_graph.="TOTAL:".trim($DNCcountPCT)."%"; - for ($e=0; $e"; - } - $JS_onload.="\tDrawGraph('CALLS', '1');\n"; - $JS_text.="function DrawGraph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$CALLS_graph\";\n"; - $JS_text.=" var CICALLS_graph=\"$CICALLS_graph\";\n"; - $JS_text.=" var DNCCI_graph=\"$DNCCI_graph\";\n"; - for ($e=0; $e
 


"; - - # echo $GRAPH.$GRAPH2.$GRAPH3.$max; + $graph_count=count($graph_array); + $graph_title=_QXZ("AGENT STATUS DETAIL REPORT"); + include("graphcanvas.inc"); + $GRAPH.=$graphCanvas; } else { @@ -1102,8 +1125,7 @@ echo ""; if ($report_display_type=="HTML") { - echo $GRAPH.$GRAPH2.$GRAPH3; - echo $JS_text; + echo $GRAPH.$JS_text; } else { diff --git a/agc_2-X/trunk/www/vicidial/AST_agent_time_detail.php b/agc_2-X/trunk/www/vicidial/AST_agent_time_detail.php index ff61685b..f4e4e23c 100644 --- a/agc_2-X/trunk/www/vicidial/AST_agent_time_detail.php +++ b/agc_2-X/trunk/www/vicidial/AST_agent_time_detail.php @@ -49,6 +49,7 @@ # 160301-2051 - Expanded full name to 25 characters on text display # 160330-0649 - Fixed issue with names and non-latin setting # 160411-1958 - Fixed issue with download field order +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -476,6 +477,9 @@ if ($file_download < 1) echo "\n"; echo "\n"; echo "\n"; + require("chart_button.php"); + echo "\n"; + echo "\n"; echo "\n"; echo ""._QXZ("$report_name")."\n"; @@ -573,32 +577,7 @@ else $max_pause=1; $max_dead=1; $max_customer=1; - $GRAPH.=""; - $GRAPH2=""; - if ($show_parks) { - $GRAPH2.=""; - } - $GRAPH2.=""; - $graph_header="
"._QXZ("CALLS").""._QXZ("TIME CLOCK").""._QXZ("LOGIN TIME").""._QXZ("PARKS").""._QXZ("PARKTIME").""._QXZ("AVGPARK").""._QXZ("PARKS/CALL").""._QXZ("WAIT").""._QXZ("WAIT")." %"._QXZ("TALK").""._QXZ("TALKTIME")."%"._QXZ("DISPO").""._QXZ("DISPOTIME")."%"._QXZ("PAUSE").""._QXZ("PAUSETIME")."%"._QXZ("DEAD").""._QXZ("DEADTIME")."%"._QXZ("CUSTOMER")."
"; - $CALLS_graph=$graph_header.""; - $TIMECLOCK_graph=$graph_header.""; - $AGENTTIME_graph=$graph_header.""; - $WAIT_graph=$graph_header.""; - $WAITPCT_graph=$graph_header.""; - $TALK_graph=$graph_header.""; - $TALKPCT_graph=$graph_header.""; - $DISPO_graph=$graph_header.""; - $DISPOPCT_graph=$graph_header.""; - $PAUSE_graph=$graph_header.""; - $PAUSEPCT_graph=$graph_header.""; - $DEAD_graph=$graph_header.""; - $DEADPCT_graph=$graph_header.""; - $CUSTOMER_graph=$graph_header.""; - $PARKS_graph=$graph_header.""; - $PARKTIME_graph=$graph_header.""; - $AVGPARK_graph=$graph_header.""; - $PARKSCALL_graph=$graph_header.""; - + while ($i < $users_to_print) { $row=mysqli_fetch_row($rslt); @@ -951,12 +930,14 @@ else ### BEGIN loop through each status ### $n=0; + $sub_status_array=array(); while ($n < $sub_status_count) { $Sstatus=$sub_statusesARY[$n]; $SstatusTXT=''; $varname=$Sstatus."_graph"; $$varname=$graph_header.""; + array_push($sub_status_array, "ATD_SUBSTATUS".$n."data|$n|$Sstatus|sub_status_array"); $max_varname="max_".$Sstatus; ### BEGIN loop through each stat line ### $i=0; $status_found=0; @@ -971,6 +952,9 @@ else if ($PCpause_sec[$i]>$$max_varname) {$$max_varname=$PCpause_sec[$i];} $graph_stats_sub[$m][$n]=$PCpause_sec[$i]; + $n1=($n+19); # THIS IS FOR THE GRAPHING FURTHER DOWN; COULDN'T THINK OF A BETTER WAY TO DO THIS. + $graph_stats[$m][$n1]=$PCpause_sec[$i]; + $SstatusTXT = sprintf("%10s", $pfUSERcodePAUSE_MS); $SstatusesHTML .= " $SstatusTXT |"; $SstatusesFILE .= ",$USERcodePAUSE_MS"; @@ -1296,116 +1280,102 @@ else $Sstatus=$sub_statusesARY[$e]; $SstatusTXT=$Sstatus; if ($Sstatus=="") {$SstatusTXT="(blank)";} - $GRAPH2.=""; } - for ($d=0; $d 0) - { - $CALLS_graph.=" "; - } - else - { - $CALLS_graph.=" "; - } - $TIMECLOCK_graph.=" "; - $AGENTTIME_graph.=" "; - $WAIT_graph.=" "; - $TALK_graph.=" "; - $DISPO_graph.=" "; - $PAUSE_graph.=" "; - $DEAD_graph.=" "; - $CUSTOMER_graph.=" "; - $TALKPCT_graph.=" "; - $DISPOPCT_graph.=" "; - $PAUSEPCT_graph.=" "; - $DEADPCT_graph.=" "; - $WAITPCT_graph.=" "; - $PARKS_graph.=" "; - $PARKTIME_graph.=" "; - $AVGPARK_graph.=" "; - $PARKSCALL_graph.=" "; - for ($e=0; $e\n"; + # USE THIS FOR COMBINED graphs, use pipe-delimited array elements, dataset_name|index|link_name|graph_override + # You have to hard code the graph name in where it is overridden and mind the data indices. No other way to do it. + $multigraph_text=""; + $graph_id++; + $graph_array=array("ATD_CALLSdata|1|CALLS|integer|", "ATD_TIMECLOCKdata|2|TIME CLOCK|time|", "ATD_LOGINTIMEdata|3|LOGIN TIME|time|"); + if ($show_parks) { + array_push($graph_array, "ATD_PARKSdata|15|PARKS|integer|", "ATD_PARKTIMEdata|16|PARKTIME|time|", "ATD_AVGPARKdata|17|AVGPARK|time|", "ATD_PARKSCALLdata|18|PARKS/CALL|decimal|"); + } + array_push($graph_array, "ATD_WAITdata|4|WAIT|time|", "ATD_WAITPCTdata|14|WAIT %|percent|", "ATD_TALKdata|5|TALK|time|", "ATD_TALKTIMEPCTdata|10|TALKTIME%|percent|", "ATD_DISPOdata|6|DISPO|time|", "ATD_DISPOTIMEPCTdata|11|DISPOTIME%|percent|", "ATD_PAUSEdata|7|PAUSE|time|", "ATD_PAUSETIMEPCTdata|12|PAUSETIME%|percent|", "ATD_DEADdata|8|DEAD|time|", "ATD_DEADTIMEPCTdata|13|DEADTIME%|percent|", "ATD_CUSTOMERdata|9|CUSTOMER|time|"); + + for ($e=0; $e"; - } - } - $CALLS_graph.="
"._QXZ("AGENT TIME BREAKDOWN")."
STATUS"._QXZ("CALLS")."
"._QXZ("TIME CLOCK")."
"._QXZ("LOGIN TIME")."
"._QXZ("WAIT")."
"._QXZ("WAIT")." %
"._QXZ("TALK")."
"._QXZ("TALK TIME")." %
"._QXZ("DISPO")."
"._QXZ("DISPO TIME")." %
"._QXZ("PAUSE")."
"._QXZ("PAUSE TIME")." %
"._QXZ("DEAD")."
"._QXZ("DEAD TIME")." %
"._QXZ("CUSTOMER")."
"._QXZ("PARKS")."
"._QXZ("PARKTIME")."
"._QXZ("AVGPARK")."
"._QXZ("PARKSCALL")."
$Sstatus
$SstatusTXT
".$graph_stats[$d][0]."".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][2], 'HF')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][3], 'HF')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][4], 'HF')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][5], 'HF')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][6], 'HF')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][7], 'HF')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][8], 'HF')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][9], 'HF')."
".$graph_stats[$d][0]."".$graph_stats[$d][10]." %
".$graph_stats[$d][0]."".$graph_stats[$d][11]." %
".$graph_stats[$d][0]."".$graph_stats[$d][12]." %
".$graph_stats[$d][0]."".$graph_stats[$d][13]." %
".$graph_stats[$d][0]."".$graph_stats[$d][14]." %
".$graph_stats[$d][0]."".$graph_stats[$d][15]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][16],'HF')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][17],'HF')."
".$graph_stats[$d][0]."".$graph_stats[$d][18]."
".sec_convert($graph_stats_sub[$d][$e], 'HF')."
"._QXZ("TOTAL").":".trim($hTOTcalls)."
"; - $TIMECLOCK_graph.=""._QXZ("TOTAL").":".trim($hTOTtimeTC).""; - $AGENTTIME_graph.=""._QXZ("TOTAL").":".trim($hTOTALtime).""; - $WAIT_graph.=""._QXZ("TOTAL").":".trim($hTOTwait).""; - $TALK_graph.=""._QXZ("TOTAL").":".trim($hTOTtalk).""; - $DISPO_graph.=""._QXZ("TOTAL").":".trim($hTOTdispo).""; - $PAUSE_graph.=""._QXZ("TOTAL").":".trim($hTOTpause).""; - $DEAD_graph.=""._QXZ("TOTAL").":".trim($hTOTdead).""; - $CUSTOMER_graph.=""._QXZ("TOTAL").":".trim($hTOTcustomer).""; - $WAITPCT_graph.=""._QXZ("AVERAGE").":".trim($hTOTwaitpct).""; - $TALKPCT_graph.=""._QXZ("AVERAGE").":".trim($hTOTtalkpct).""; - $DISPOPCT_graph.=""._QXZ("AVERAGE").":".trim($hTOTdispopct).""; - $PAUSEPCT_graph.=""._QXZ("AVERAGE").":".trim($hTOTpausepct).""; - $DEADPCT_graph.=""._QXZ("AVERAGE").":".trim($hTOTdeadpct).""; - $PARKS_graph.=""._QXZ("TOTAL").":".trim($hTOTuser_holds).""; - $PARKTIME_graph.=""._QXZ("TOTAL").":".trim($hTOTtotal_hold_time).""; - $AVGPARK_graph.=""._QXZ("AVERAGE").":".trim($hTOTavg_hold_time).""; - $PARKSCALL_graph.=""._QXZ("AVERAGE").":".trim($hTOTuser_hpc).""; - - for ($e=0; $e".trim($$total_var).""; -# $JS_text.="var ".$Sstatus."_graph=\"".$$graph_var."\";\n"; - } - $JS_onload.="\tDrawGraph('CALLS', '1');\n"; - $JS_text.="function DrawGraph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$CALLS_graph\";\n"; - $JS_text.=" var TIMECLOCK_graph=\"$TIMECLOCK_graph\";\n"; - $JS_text.=" var AGENTTIME_graph=\"$AGENTTIME_graph\";\n"; - $JS_text.=" var WAIT_graph=\"$WAIT_graph\";\n"; - $JS_text.=" var TALK_graph=\"$TALK_graph\";\n"; - $JS_text.=" var DISPO_graph=\"$DISPO_graph\";\n"; - $JS_text.=" var PAUSE_graph=\"$PAUSE_graph\";\n"; - $JS_text.=" var DEAD_graph=\"$DEAD_graph\";\n"; - $JS_text.=" var CUSTOMER_graph=\"$CUSTOMER_graph\";\n"; - $JS_text.=" var WAITPCT_graph=\"$WAITPCT_graph\";\n"; - $JS_text.=" var TALKPCT_graph=\"$TALKPCT_graph\";\n"; - $JS_text.=" var DISPOPCT_graph=\"$DISPOPCT_graph\";\n"; - $JS_text.=" var PAUSEPCT_graph=\"$PAUSEPCT_graph\";\n"; - $JS_text.=" var DEADPCT_graph=\"$DEADPCT_graph\";\n"; - $JS_text.=" var PARKS_graph=\"$PARKS_graph\";\n"; - $JS_text.=" var PARKTIME_graph=\"$PARKTIME_graph\";\n"; - $JS_text.=" var AVGPARK_graph=\"$AVGPARK_graph\";\n"; - $JS_text.=" var PARKSCALL_graph=\"$PARKSCALL_graph\";\n"; - - for ($e=0; $e"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; } - $JS_text.=" for (var i=1; i<=".(14+count($sub_statusesARY))."; i++) {\n"; - $JS_text.=" var cellID=\"timegraph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"timegraph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.="\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('agent_time_detail_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title=_QXZ("AGENT TIME DETAIL REPORT"); + include("graphcanvas.inc"); + $GRAPH.=$graphCanvas; + - $GRAPH3="
 


"; - - # echo $GRAPH.$GRAPH2.$GRAPH3.$max; } else { @@ -1569,8 +1539,8 @@ echo ""; if ($report_display_type=="HTML") { - echo $JS_text; echo $GRAPH.$GRAPH2.$GRAPH3.$max; + echo $JS_text; } else { diff --git a/agc_2-X/trunk/www/vicidial/AST_agent_timeclock_detail.php b/agc_2-X/trunk/www/vicidial/AST_agent_timeclock_detail.php index 852c572f..49966d47 100644 --- a/agc_2-X/trunk/www/vicidial/AST_agent_timeclock_detail.php +++ b/agc_2-X/trunk/www/vicidial/AST_agent_timeclock_detail.php @@ -23,6 +23,7 @@ # 141114-0905 - Finalized adding QXZ translation to all admin files # 141230-1520 - Added code for on-the-fly language translations display # 160227-1934 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -374,6 +375,10 @@ if ($file_download < 1) + + + + \n"; + + # SPECIAL EXCEPTION FOR THIS GRAPH + $graphCanvas.="\n"; + $graphCanvas.=" \n"; + $graphCanvas.=" \n"; + $graphCanvas.=" \n"; + $graphCanvas.=" \n"; + $graphCanvas.=" \n"; + for ($q=0; $q".$graph_stats[$q][0]."\n"; + $graphCanvas.=" \n"; + $graphCanvas.=" \n"; + } + $graphCanvas.="
"._QXZ("TIME CLOCK PUNCHES")."
"._QXZ("USER/USER GROUP").""._QXZ("TIME CLOCK PUNCHES")."
".$graph_stats[$q][3]."
\n"; + + $GRAPH_text.=$graphCanvas; + + $TOT_AGENTS = sprintf("%4s", $m); $k=$m; @@ -865,19 +954,13 @@ else $ASCII_text.="+-----------------+----------+----------------------+------------+--------------------\n"; $ASCII_text.="| "._QXZ("TOTALS",7,"r")." "._QXZ("AGENTS",13,"r").":$TOT_AGENTS | |$TOTtimeTC |\n"; $ASCII_text.="+----------------------------+ +------------+\n"; - $GRAPH.=" \n"; - $GRAPH.=" "._QXZ("TOTALS")."\n"; - $GRAPH.=" "._QXZ("AGENTS").": $TOT_AGENTS\n"; - $GRAPH.=" $TOTtimeTC\n"; - $GRAPH.=" \n"; - $GRAPH.=" \n"; if ($AUTOLOGOUTflag > 0) { $ASCII_text.=" * "._QXZ("denotes AUTOLOGOUT from timeclock")."\n"; - $GRAPH.=" * "._QXZ("denotes AUTOLOGOUT from timeclock")."\n"; + $GRAPH_text.=" * "._QXZ("denotes AUTOLOGOUT from timeclock")."\n"; } $ASCII_text.="
"; - $GRAPH.="
"; + $GRAPH_text.="
"; } else { @@ -935,7 +1018,7 @@ if ($file_download > 0) if ($report_display_type=="HTML") { - echo $GRAPH; + echo $GRAPH_text.$JS_text; } else { diff --git a/agc_2-X/trunk/www/vicidial/AST_campaign_status_list_report.php b/agc_2-X/trunk/www/vicidial/AST_campaign_status_list_report.php index 81ac4138..d2874efe 100644 --- a/agc_2-X/trunk/www/vicidial/AST_campaign_status_list_report.php +++ b/agc_2-X/trunk/www/vicidial/AST_campaign_status_list_report.php @@ -22,6 +22,7 @@ # 150516-1312 - Fixed Javascript element problem, Issue #857 # 151219-0107 - Added option for searching archived data # 160227-1059 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -326,6 +327,9 @@ $HTML_head.=" \n"; $HTML_head.="\n"; $HTML_head.="\n"; $HTML_head.="\n"; +require("chart_button.php"); +$HTML_head.="\n"; +$HTML_head.="\n"; $HTML_head.="\n"; $HTML_head.=""._QXZ("$report_name")."$group_S\n"; @@ -472,7 +476,6 @@ while($i < $group_ct) $dispo_ary=""; $ASCII_text.=""._QXZ("List ID")." #$list_id: $list_name\n"; - $GRAPH.=""._QXZ("List ID")." #$list_id: $list_name\n"; $CSV_text.="\""._QXZ("List ID")." #$list_id: $list_name\"\n"; @@ -482,13 +485,6 @@ while($i < $group_ct) $stat_rslt=mysql_to_mysqli($stat_stmt, $link); if (mysqli_num_rows($stat_rslt)>0) { - $GRAPH.=""; - $GRAPH.=""; - $GRAPH.="
"._QXZ("CALLS").""._QXZ("DURATION").""._QXZ("HANDLE TIME")."

 


"; - $graph_header=""; - $CALLS_graph=$graph_header.""; - $DURATION_graph=$graph_header.""; - $HANDLETIME_graph=$graph_header.""; $total_calls=0; $total_handle_time=0; $total_duration=0; @@ -589,33 +585,86 @@ while($i < $group_ct) $ASCII_text .= "| "._QXZ("Completed:",19)." $COMP_count $COMP_percent% |\n"; $ASCII_text .= "+--------------------------------------------------------------+\n"; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("CSL_CALLS".$list_id."data|1|CALLS|integer|", "CSL_DURATION".$list_id."data|2|DURATION|time|", "CSL_HANDLETIME".$list_id."data|3|HANDLE TIME|time|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); - for ($d=0; $d"; - $DURATION_graph.=" "; - $HANDLETIME_graph.=" "; + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; } - $CALLS_graph.="
"._QXZ("List ID")." #$list_id: $list_name
"._QXZ("DISPOSITION").""._QXZ("CALLS")."
"._QXZ("DURATION")."
"._QXZ("HANDLE TIME")."
".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][2], 'H')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][3], 'H')."
"._QXZ("TOTAL").": $current_graph_total
TOTAL:".trim($total_calls)."
"; - $DURATION_graph.="TOTAL:".sec_convert($total_duration, 'H').""; - $HANDLETIME_graph.="TOTAL:".sec_convert($total_handle_time, 'H').""; - $JS_onload.="\tDraw".$list_id."Graph('CALLS', '1');\n"; - $JS_text.="function Draw".$list_id."Graph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$CALLS_graph\";\n"; - $JS_text.=" var DURATION_graph=\"$DURATION_graph\";\n"; - $JS_text.=" var HANDLETIME_graph=\"$HANDLETIME_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=3; i++) {\n"; - $JS_text.=" var cellID=\"list_".$list_id."_graph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"list_".$list_id."_graph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('stats_".$list_id."_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - #$HTML_text.=$GRAPH; + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title=""._QXZ("List ID")." #$list_id: $list_name"; + include("graphcanvas.inc"); + $GRAPH.=$graphCanvas; + } else { @@ -637,7 +686,7 @@ $JS_text.="\n"; if ($report_display_type=="HTML") { - $HTML_text.=$JS_text.$GRAPH; + $HTML_text.=$GRAPH.$JS_text; } else { diff --git a/agc_2-X/trunk/www/vicidial/AST_inbound_daily_report.php b/agc_2-X/trunk/www/vicidial/AST_inbound_daily_report.php index 7c551fd7..418958cb 100644 --- a/agc_2-X/trunk/www/vicidial/AST_inbound_daily_report.php +++ b/agc_2-X/trunk/www/vicidial/AST_inbound_daily_report.php @@ -26,6 +26,7 @@ # 150516-1313 - Fixed Javascript element problem, Issue #857 # 151125-1629 - Added search archive option # 160227-1142 - Uniform form format +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -370,7 +371,6 @@ $HEADER.=" .red {color: black; background-color: #FF9999}\n"; $HEADER.=" .orange {color: black; background-color: #FFCC99}\n"; $HEADER.="-->\n"; $HEADER.=" \n"; - #if (!preg_match("/\|$group\|/i",$groups_string)) # { # $HEADER.="\n"; @@ -380,6 +380,9 @@ $HEADER.=" \n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; +require("chart_button.php"); +$HEADER.="\n"; +$HEADER.="\n"; $HEADER.="\n"; $HEADER.=""._QXZ("$report_name")."\n"; @@ -1108,23 +1111,6 @@ else $max_qtd_totaltalktime=1; $max_qtd_totalwraptime=1; $max_qtd_totalcalltime=1; - $GRAPH="
"._QXZ("TOTAL CALLS OFFERED").""._QXZ("TOTAL CALLS ANSWERED").""._QXZ("TOTAL AGENTS ANSWERED").""._QXZ("TOTAL CALLS ABANDONED").""._QXZ("TOTAL ABANDON PERCENT").""._QXZ("AVG ABANDON TIME").""._QXZ("AVG ANSWER SPEED").""._QXZ("AVG TALK TIME").""._QXZ("TOTAL TALK TIME").""._QXZ("TOTAL WRAP TIME").""._QXZ("TOTAL CALL TIME")."

 


"; - $MTD_GRAPH="

"._QXZ("TOTAL CALLS OFFERED").""._QXZ("TOTAL CALLS ANSWERED").""._QXZ("TOTAL AGENTS ANSWERED").""._QXZ("TOTAL CALLS ABANDONED").""._QXZ("TOTAL ABANDON PERCENT").""._QXZ("AVG ABANDON TIME").""._QXZ("AVG ANSWER SPEED").""._QXZ("AVG TALK TIME").""._QXZ("TOTAL TALK TIME").""._QXZ("TOTAL WRAP TIME").""._QXZ("TOTAL CALL TIME")."

 


"; - $WTD_GRAPH="

"._QXZ("TOTAL CALLS OFFERED").""._QXZ("TOTAL CALLS ANSWERED").""._QXZ("TOTAL AGENTS ANSWERED").""._QXZ("TOTAL CALLS ABANDONED").""._QXZ("TOTAL ABANDON PERCENT").""._QXZ("AVG ABANDON TIME").""._QXZ("AVG ANSWER SPEED").""._QXZ("AVG TALK TIME").""._QXZ("TOTAL TALK TIME").""._QXZ("TOTAL WRAP TIME").""._QXZ("TOTAL CALL TIME")."

 


"; - $QTD_GRAPH="

"._QXZ("TOTAL CALLS OFFERED").""._QXZ("TOTAL CALLS ANSWERED").""._QXZ("TOTAL AGENTS ANSWERED").""._QXZ("TOTAL CALLS ABANDONED").""._QXZ("TOTAL ABANDON PERCENT").""._QXZ("AVG ABANDON TIME").""._QXZ("AVG ANSWER SPEED").""._QXZ("AVG TALK TIME").""._QXZ("TOTAL TALK TIME").""._QXZ("TOTAL WRAP TIME").""._QXZ("TOTAL CALL TIME")."

 


"; - - $graph_header=""; - $OFFERED_graph=$graph_header.""; - $ANSWERED_graph=$graph_header.""; - $AGENTS_graph=$graph_header.""; - $ABANDONED_graph=$graph_header.""; - $ABANDONPCT_graph=$graph_header.""; - $AVGABANDONTIME_graph=$graph_header.""; - $AVGANSWERSPEED_graph=$graph_header.""; - $AVGTALKTIME_graph=$graph_header.""; - $TOTALTALKTIME_graph=$graph_header.""; - $TOTALWRAPTIME_graph=$graph_header.""; - $TOTALCALLTIME_graph=$graph_header.""; ########################## $totCALLSwtd=0; @@ -1593,32 +1579,87 @@ else $wtd_graph_stats[$wa][9]=trim($totANSWERSwrapTIMEwtd); $wtd_graph_stats[$wa][10]=trim($totANSWERStotTIMEwtd); $wtd_graph_stats[$wa][17]=trim($totAGENTSwtd); - $wtd_OFFERED_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"), $OFFERED_graph); - $wtd_ANSWERED_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$ANSWERED_graph); - $wtd_AGENTS_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"), $AGENTS_graph); - $wtd_ABANDONED_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$ABANDONED_graph); - $wtd_ABANDONPCT_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$ABANDONPCT_graph); - $wtd_AVGABANDONTIME_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$AVGABANDONTIME_graph); - $wtd_AVGANSWERSPEED_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$AVGANSWERSPEED_graph); - $wtd_AVGTALKTIME_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$AVGTALKTIME_graph); - $wtd_TOTALTALKTIME_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$TOTALTALKTIME_graph); - $wtd_TOTALWRAPTIME_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$TOTALWRAPTIME_graph); - $wtd_TOTALCALLTIME_graph=preg_replace('/DAILY/', _QXZ("WEEK-TO-DATE"),$TOTALCALLTIME_graph); - for ($q=0; $q"; - $wtd_ANSWERED_graph.=" "; - $wtd_AGENTS_graph.=" "; - $wtd_ABANDONED_graph.=" "; - $wtd_ABANDONPCT_graph.=" "; - $wtd_AVGABANDONTIME_graph.=" "; - $wtd_AVGANSWERSPEED_graph.=" "; - $wtd_AVGTALKTIME_graph.=" "; - $wtd_TOTALTALKTIME_graph.=" "; - $wtd_TOTALWRAPTIME_graph.=" "; - $wtd_TOTALCALLTIME_graph.=" "; + + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("IDR_wtd_TOTALCALLSOFFEREDdata|1|TOTAL CALLS OFFERED|integer|", "IDR_wtd_TOTALCALLSANSWEREDdata|2|TOTAL CALLS ANSWERED|integer|", "IDR_wtd_TOTALAGENTSANSWEREDdata|17|TOTAL AGENTS ANSWERED|integer|", "IDR_wtd_TOTALCALLSABANDONEDdata|3|TOTAL CALLS ABANDONED|integer|", "IDR_wtd_TOTALABANDONPERCENTdata|4|TOTAL ABANDON PERCENT|percent|", "IDR_wtd_AVGABANDONTIMEdata|11|AVG ABANDON TIME|time|", "IDR_wtd_AVGANSWERSPEEDdata|12|AVG ANSWER SPEED|time|", "IDR_wtd_AVGTALKTIMEdata|16|AVG TALK TIME|time|", "IDR_wtd_TOTALTALKTIMEdata|15|TOTAL TALK TIME|time|", "IDR_wtd_TOTALWRAPTIMEdata|13|TOTAL WRAP TIME|time|", "IDR_wtd_TOTALCALLTIMEdata|14|TOTAL CALL TIME|time|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } + $graph_count=count($graph_array); + $graph_title=_QXZ("WEEKLY REPORT")." - $query_date_BEGIN "._QXZ("to")." $query_date_END"; + include("graphcanvas.inc"); + $WTD_GRAPH=$graphCanvas; + $ASCII_text.="$MAINH\n"; $ASCII_text.="| "._QXZ("Week to date",41,"r")." | $totCALLSwtd | $totANSWERSwtd | $totAGENTSwtd | $totABANDONSwtd | $totABANDONSpctwtd%| $totABANDONSavgTIMEwtd | $totANSWERSavgspeedTIMEwtd | $totANSWERSavgTIMEwtd | $totANSWERStalkTIMEwtd | $totANSWERSwrapTIMEwtd | $totANSWERStotTIMEwtd |"; $CSV_text.="\""._QXZ("WTD")."\",\"$totCALLSwtd\",\"$totANSWERSwtd\",\"$totAGENTSwtd\",\"$totABANDONSwtd\",\"$totABANDONSpctwtd%\",\"$totABANDONSavgTIMEwtd\",\"$totANSWERSavgspeedTIMEwtd\",\"$totANSWERSavgTIMEwtd\",\"$totANSWERStalkTIMEwtd\",\"$totANSWERSwrapTIMEwtd\",\"$totANSWERStotTIMEwtd\""; @@ -1689,42 +1730,86 @@ else $mtd_graph_stats[$ma][9]=trim($totANSWERSwrapTIMEmtd); $mtd_graph_stats[$ma][10]=trim($totANSWERStotTIMEmtd); $wtd_graph_stats[$ma][17]=trim($totAGENTSmtd); - $mtd_OFFERED_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$OFFERED_graph); - $mtd_ANSWERED_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$ANSWERED_graph); - $mtd_AGENTS_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"), $AGENTS_graph); - $mtd_ABANDONED_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$ABANDONED_graph); - $mtd_ABANDONPCT_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$ABANDONPCT_graph); - $mtd_AVGABANDONTIME_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$AVGABANDONTIME_graph); - $mtd_AVGANSWERSPEED_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$AVGANSWERSPEED_graph); - $mtd_AVGTALKTIME_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$AVGTALKTIME_graph); - $mtd_TOTALTALKTIME_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$TOTALTALKTIME_graph); - $mtd_TOTALWRAPTIME_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$TOTALWRAPTIME_graph); - $mtd_TOTALCALLTIME_graph=preg_replace('/DAILY/', _QXZ("MONTH-TO-DATE"),$TOTALCALLTIME_graph); - for ($q=0; $q"; - $mtd_ANSWERED_graph.=" "; - $mtd_AGENTS_graph.=" "; - $mtd_ABANDONED_graph.=" "; - $mtd_ABANDONPCT_graph.=" "; - $mtd_AVGABANDONTIME_graph.=" "; - $mtd_AVGANSWERSPEED_graph.=" "; - $mtd_AVGTALKTIME_graph.=" "; - $mtd_TOTALTALKTIME_graph.=" "; - $mtd_TOTALWRAPTIME_graph.=" "; - $mtd_TOTALCALLTIME_graph.=" "; - $graph_totCALLSmtd+=$mtd_graph_stats[$q][1]; - $graph_totANSWERSmtd+=$mtd_graph_stats[$q][2]; - $graph_totAGENTSmtd+=$mtd_graph_stats[$q][17]; - $graph_totABANDONSmtd+=$mtd_graph_stats[$q][3]; - $graph_totABANDONSpctmtd+=$mtd_graph_stats[$q][4]; - $graph_totABANDONSavgTIMEmtd+=$mtd_graph_stats[$q][5]; - $graph_totANSWERSavgspeedTIMEmtd+=$mtd_graph_stats[$q][6]; - $graph_totANSWERSavgTIMEmtd+=$mtd_graph_stats[$q][7]; - $graph_totANSWERStalkTIMEmtd+=$mtd_graph_stats[$q][8]; - $graph_totANSWERSwrapTIMEmtd+=$mtd_graph_stats[$q][9]; - $graph_totANSWERStotTIMEmtd+=$mtd_graph_stats[$q][10]; - } + + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("IDR_mtd_TOTALCALLSOFFEREDdata|1|TOTAL CALLS OFFERED|integer|", "IDR_mtd_TOTALCALLSANSWEREDdata|2|TOTAL CALLS ANSWERED|integer|", "IDR_mtd_TOTALAGENTSANSWEREDdata|17|TOTAL AGENTS ANSWERED|integer|", "IDR_mtd_TOTALCALLSABANDONEDdata|3|TOTAL CALLS ABANDONED|integer|", "IDR_mtd_TOTALABANDONPERCENTdata|4|TOTAL ABANDON PERCENT|percent|", "IDR_mtd_AVGABANDONTIMEdata|11|AVG ABANDON TIME|time|", "IDR_mtd_AVGANSWERSPEEDdata|12|AVG ANSWER SPEED|time|", "IDR_mtd_AVGTALKTIMEdata|16|AVG TALK TIME|time|", "IDR_mtd_TOTALTALKTIMEdata|15|TOTAL TALK TIME|time|", "IDR_mtd_TOTALWRAPTIMEdata|13|TOTAL WRAP TIME|time|", "IDR_mtd_TOTALCALLTIMEdata|14|TOTAL CALL TIME|time|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; + } + + $graph_count=count($graph_array); + $graph_title=_QXZ("MONTHLY REPORT")." - $query_date_BEGIN "._QXZ("to")." $query_date_END"; + include("graphcanvas.inc"); + $MTD_GRAPH=$graphCanvas; $ASCII_text.="$MAINH\n"; $ASCII_text.="| "._QXZ("Month to date",41,"r")." | $totCALLSmtd | $totANSWERSmtd | $totAGENTSmtd | $totABANDONSmtd | $totABANDONSpctmtd%| $totABANDONSavgTIMEmtd | $totANSWERSavgspeedTIMEmtd | $totANSWERSavgTIMEmtd | $totANSWERStalkTIMEmtd | $totANSWERSwrapTIMEmtd | $totANSWERStotTIMEmtd |"; @@ -1808,43 +1893,89 @@ else $qtd_graph_stats[$qa][9]=trim($totANSWERSwrapTIMEqtd); $qtd_graph_stats[$qa][10]=trim($totANSWERStotTIMEqtd); $qtd_graph_stats[$qa][17]=trim($totAGENTSqtd); - $qtd_OFFERED_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$OFFERED_graph); - $qtd_ANSWERED_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$ANSWERED_graph); - $qtd_AGENTS_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$AGENTS_graph); - $qtd_ABANDONED_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$ABANDONED_graph); - $qtd_ABANDONPCT_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$ABANDONPCT_graph); - $qtd_AVGABANDONTIME_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$AVGABANDONTIME_graph); - $qtd_AVGANSWERSPEED_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$AVGANSWERSPEED_graph); - $qtd_AVGTALKTIME_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$AVGTALKTIME_graph); - $qtd_TOTALTALKTIME_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$TOTALTALKTIME_graph); - $qtd_TOTALWRAPTIME_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$TOTALWRAPTIME_graph); - $qtd_TOTALCALLTIME_graph=preg_replace('/DAILY/', _QXZ("QUARTER-TO-DATE"),$TOTALCALLTIME_graph); - for ($q=0; $q"; - $qtd_ANSWERED_graph.=" "; - $qtd_AGENTS_graph.=" "; - $qtd_ABANDONED_graph.=" "; - $qtd_ABANDONPCT_graph.=" "; - $qtd_AVGABANDONTIME_graph.=" "; - $qtd_AVGANSWERSPEED_graph.=" "; - $qtd_AVGTALKTIME_graph.=" "; - $qtd_TOTALTALKTIME_graph.=" "; - $qtd_TOTALWRAPTIME_graph.=" "; - $qtd_TOTALCALLTIME_graph.=" "; - $graph_totCALLSqtd+=$qtd_graph_stats[$q][1]; - $graph_totANSWERSqtd+=$qtd_graph_stats[$q][2]; - $graph_totAGENTSqtd+=$qtd_graph_stats[$q][17]; - $graph_totABANDONSqtd+=$qtd_graph_stats[$q][3]; - $graph_totABANDONSpctqtd+=$qtd_graph_stats[$q][4]; - $graph_totABANDONSavgTIMEqtd+=$qtd_graph_stats[$q][5]; - $graph_totANSWERSavgspeedTIMEqtd+=$qtd_graph_stats[$q][6]; - $graph_totANSWERSavgTIMEqtd+=$qtd_graph_stats[$q][7]; - $graph_totANSWERStalkTIMEqtd+=$qtd_graph_stats[$q][8]; - $graph_totANSWERSwrapTIMEqtd+=$qtd_graph_stats[$q][9]; - $graph_totANSWERStotTIMEqtd+=$qtd_graph_stats[$q][10]; + + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("IDR_qtd_TOTALCALLSOFFEREDdata|1|TOTAL CALLS OFFERED|integer|", "IDR_qtd_TOTALCALLSANSWEREDdata|2|TOTAL CALLS ANSWERED|integer|", "IDR_qtd_TOTALAGENTSANSWEREDdata|17|TOTAL AGENTS ANSWERED|integer|", "IDR_qtd_TOTALCALLSABANDONEDdata|3|TOTAL CALLS ABANDONED|integer|", "IDR_qtd_TOTALABANDONPERCENTdata|4|TOTAL ABANDON PERCENT|percent|", "IDR_qtd_AVGABANDONTIMEdata|11|AVG ABANDON TIME|time|", "IDR_qtd_AVGANSWERSPEEDdata|12|AVG ANSWER SPEED|time|", "IDR_qtd_AVGTALKTIMEdata|16|AVG TALK TIME|time|", "IDR_qtd_TOTALTALKTIMEdata|15|TOTAL TALK TIME|time|", "IDR_qtd_TOTALWRAPTIMEdata|13|TOTAL WRAP TIME|time|", "IDR_qtd_TOTALCALLTIMEdata|14|TOTAL CALL TIME|time|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } + $graph_count=count($graph_array); + $graph_title=_QXZ("QUARTERLY REPORT")." - $query_date_BEGIN "._QXZ("to")." $query_date_END"; + include("graphcanvas.inc"); + $QTD_GRAPH=$graphCanvas; + + $ASCII_text.="$MAINH\n"; $ASCII_text.="| "._QXZ("Quarter to date",41,"r")." | $totCALLSqtd | $totANSWERSqtd | $totAGENTSqtd | $totABANDONSqtd | $totABANDONSpctqtd%| $totABANDONSavgTIMEqtd | $totANSWERSavgspeedTIMEqtd | $totANSWERSavgTIMEqtd | $totANSWERStalkTIMEqtd | $totANSWERSwrapTIMEqtd | $totANSWERStotTIMEqtd |"; $CSV_text.="\""._QXZ("Quarter to date")."\",\"$totCALLSqtd\",\"$totANSWERSqtd\",\"$totAGENTSqtd\",\"$totABANDONSqtd\",\"$totABANDONSpctqtd%\",\"$totABANDONSavgTIMEqtd\",\"$totANSWERSavgspeedTIMEqtd\",\"$totANSWERSavgTIMEqtd\",\"$totANSWERStalkTIMEqtd\",\"$totANSWERSwrapTIMEqtd\",\"$totANSWERStotTIMEqtd\""; @@ -1865,156 +1996,87 @@ else # } } - for ($q=0; $q"; - $ANSWERED_graph.=" "; - $AGENTS_graph.=" "; - $ABANDONED_graph.=" "; - $ABANDONPCT_graph.=" "; - $AVGABANDONTIME_graph.=" "; - $AVGANSWERSPEED_graph.=" "; - $AVGTALKTIME_graph.=" "; - $TOTALTALKTIME_graph.=" "; - $TOTALWRAPTIME_graph.=" "; - $TOTALCALLTIME_graph.=" "; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("IDR_TOTALCALLSOFFEREDdata|1|TOTAL CALLS OFFERED|integer|", "IDR_TOTALCALLSANSWEREDdata|2|TOTAL CALLS ANSWERED|integer|", "IDR_TOTALAGENTSANSWEREDdata|17|TOTAL AGENTS ANSWERED|integer|", "IDR_TOTALCALLSABANDONEDdata|3|TOTAL CALLS ABANDONED|integer|", "IDR_TOTALABANDONPERCENTdata|4|TOTAL ABANDON PERCENT|percent|", "IDR_AVGABANDONTIMEdata|11|AVG ABANDON TIME|time|", "IDR_AVGANSWERSPEEDdata|12|AVG ANSWER SPEED|time|", "IDR_AVGTALKTIMEdata|16|AVG TALK TIME|time|", "IDR_TOTALTALKTIMEdata|15|TOTAL TALK TIME|time|", "IDR_TOTALWRAPTIMEdata|13|TOTAL WRAP TIME|time|", "IDR_TOTALCALLTIMEdata|14|TOTAL CALL TIME|time|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $OFFERED_graph.="
"._QXZ("DAILY RPT")." - $query_date_BEGIN "._QXZ("to")." $query_date_END
"._QXZ("DATE/TIME RANGE").""._QXZ("TOTAL CALLS OFFERED")."
"._QXZ("TOTAL CALLS ANSWERED")."
"._QXZ("TOTAL AGENTS ANSWERED")."
"._QXZ("TOTAL CALLS ABANDONED")."
"._QXZ("TOTAL ABANDON PERCENT")."
"._QXZ("AVG ABANDON TIME")."
"._QXZ("AVG ANSWER SPEED")."
"._QXZ("AVG TALK TIME")."
"._QXZ("TOTAL TALK TIME")."
"._QXZ("TOTAL WRAP TIME")."
"._QXZ("TOTAL CALL TIME")."
".$wtd_graph_stats[$q][1]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][2]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][17]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][3]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][4]."%
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][5]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][6]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][7]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][8]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][9]."
".$wtd_graph_stats[$q][0]."".$wtd_graph_stats[$q][10]."
"._QXZ("TOTAL").": $current_graph_total
".$mtd_graph_stats[$q][1]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][2]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][17]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][3]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][4]."%
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][5]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][6]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][7]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][8]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][9]."
".$mtd_graph_stats[$q][0]."".$mtd_graph_stats[$q][10]."
"._QXZ("TOTAL").": $current_graph_total
".$qtd_graph_stats[$q][1]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][2]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][17]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][3]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][4]."%
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][5]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][6]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][7]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][8]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][9]."
".$qtd_graph_stats[$q][0]."".$qtd_graph_stats[$q][10]."
"._QXZ("TOTAL").": $current_graph_total
".$graph_stats[$q][1]."
".$graph_stats[$q][0]."".$graph_stats[$q][2]."
".$graph_stats[$q][0]."".$graph_stats[$q][17]."
".$graph_stats[$q][0]."".$graph_stats[$q][3]."
".$graph_stats[$q][0]."".$graph_stats[$q][4]."%
".$graph_stats[$q][0]."".$graph_stats[$q][5]."
".$graph_stats[$q][0]."".$graph_stats[$q][6]."
".$graph_stats[$q][0]."".$graph_stats[$q][7]."
".$graph_stats[$q][0]."".$graph_stats[$q][8]."
".$graph_stats[$q][0]."".$graph_stats[$q][9]."
".$graph_stats[$q][0]."".$graph_stats[$q][10]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($FtotCALLS)."
"; - $ANSWERED_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERS).""; - $AGENTS_graph.=""._QXZ("TOTAL").":".trim($FtotAGENTS).""; - $ABANDONED_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONS).""; - $ABANDONPCT_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONSpct)."%"; - $AVGABANDONTIME_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONSavgTIME).""; - $AVGANSWERSPEED_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSavgspeedTIME).""; - $AVGTALKTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSavgTIME).""; - $TOTALTALKTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERStalkTIME).""; - $TOTALWRAPTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSwrapTIME).""; - $TOTALCALLTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERStotTIME).""; - $JS_onload.="\tDrawGraph('OFFERED', '1');\n"; - $JS_text.="function DrawGraph(graph, th_id) {\n"; - $JS_text.=" var OFFERED_graph=\"$OFFERED_graph\";\n"; - $JS_text.=" var ANSWERED_graph=\"$ANSWERED_graph\";\n"; - $JS_text.=" var AGENTS_graph=\"$AGENTS_graph\";\n"; - $JS_text.=" var ABANDONED_graph=\"$ABANDONED_graph\";\n"; - $JS_text.=" var ABANDONPCT_graph=\"$ABANDONPCT_graph\";\n"; - $JS_text.=" var AVGABANDONTIME_graph=\"$AVGABANDONTIME_graph\";\n"; - $JS_text.=" var AVGANSWERSPEED_graph=\"$AVGANSWERSPEED_graph\";\n"; - $JS_text.=" var AVGTALKTIME_graph=\"$AVGTALKTIME_graph\";\n"; - $JS_text.=" var TOTALTALKTIME_graph=\"$TOTALTALKTIME_graph\";\n"; - $JS_text.=" var TOTALWRAPTIME_graph=\"$TOTALWRAPTIME_graph\";\n"; - $JS_text.=" var TOTALCALLTIME_graph=\"$TOTALCALLTIME_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=10; i++) {\n"; - $JS_text.=" var cellID=\"multigroup_graph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"multigroup_graph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('stats_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $wtd_OFFERED_graph.=""._QXZ("TOTAL").":".trim($FtotCALLS).""; - $wtd_ANSWERED_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERS).""; - $wtd_AGENTS_graph.=""._QXZ("TOTAL").":".trim($FtotAGENTS).""; - $wtd_ABANDONED_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONS).""; - $wtd_ABANDONPCT_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONSpct)."%"; - $wtd_AVGABANDONTIME_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONSavgTIME).""; - $wtd_AVGANSWERSPEED_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSavgspeedTIME).""; - $wtd_AVGTALKTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSavgTIME).""; - $wtd_TOTALTALKTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERStalkTIME).""; - $wtd_TOTALWRAPTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSwrapTIME).""; - $wtd_TOTALCALLTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERStotTIME).""; - $JS_onload.="\tDrawWTDGraph('OFFERED', '1');\n"; - $JS_text.="function DrawWTDGraph(graph, th_id) {\n"; - $JS_text.=" var OFFERED_graph=\"$wtd_OFFERED_graph\";\n"; - $JS_text.=" var ANSWERED_graph=\"$wtd_ANSWERED_graph\";\n"; - $JS_text.=" var AGENTS_graph=\"$wtd_AGENTS_graph\";\n"; - $JS_text.=" var ABANDONED_graph=\"$wtd_ABANDONED_graph\";\n"; - $JS_text.=" var ABANDONPCT_graph=\"$wtd_ABANDONPCT_graph\";\n"; - $JS_text.=" var AVGABANDONTIME_graph=\"$wtd_AVGABANDONTIME_graph\";\n"; - $JS_text.=" var AVGANSWERSPEED_graph=\"$wtd_AVGANSWERSPEED_graph\";\n"; - $JS_text.=" var AVGTALKTIME_graph=\"$wtd_AVGTALKTIME_graph\";\n"; - $JS_text.=" var TOTALTALKTIME_graph=\"$wtd_TOTALTALKTIME_graph\";\n"; - $JS_text.=" var TOTALWRAPTIME_graph=\"$wtd_TOTALWRAPTIME_graph\";\n"; - $JS_text.=" var TOTALCALLTIME_graph=\"$wtd_TOTALCALLTIME_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=10; i++) {\n"; - $JS_text.=" var cellID=\"WTD_graph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"WTD_graph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('WTD_stats_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $mtd_OFFERED_graph.=""._QXZ("TOTAL").":".trim($FtotCALLS).""; - $mtd_ANSWERED_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERS).""; - $mtd_AGENTS_graph.=""._QXZ("TOTAL").":".trim($FtotAGENTS).""; - $mtd_ABANDONED_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONS).""; - $mtd_ABANDONPCT_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONSpct)."%"; - $mtd_AVGABANDONTIME_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONSavgTIME).""; - $mtd_AVGANSWERSPEED_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSavgspeedTIME).""; - $mtd_AVGTALKTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSavgTIME).""; - $mtd_TOTALTALKTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERStalkTIME).""; - $mtd_TOTALWRAPTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSwrapTIME).""; - $mtd_TOTALCALLTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERStotTIME).""; - $JS_onload.="\tDrawMTDGraph('OFFERED', '1');\n"; - $JS_text.="function DrawMTDGraph(graph, th_id) {\n"; - $JS_text.=" var OFFERED_graph=\"$mtd_OFFERED_graph\";\n"; - $JS_text.=" var ANSWERED_graph=\"$mtd_ANSWERED_graph\";\n"; - $JS_text.=" var AGENTS_graph=\"$mtd_AGENTS_graph\";\n"; - $JS_text.=" var ABANDONED_graph=\"$mtd_ABANDONED_graph\";\n"; - $JS_text.=" var ABANDONPCT_graph=\"$mtd_ABANDONPCT_graph\";\n"; - $JS_text.=" var AVGABANDONTIME_graph=\"$mtd_AVGABANDONTIME_graph\";\n"; - $JS_text.=" var AVGANSWERSPEED_graph=\"$mtd_AVGANSWERSPEED_graph\";\n"; - $JS_text.=" var AVGTALKTIME_graph=\"$mtd_AVGTALKTIME_graph\";\n"; - $JS_text.=" var TOTALTALKTIME_graph=\"$mtd_TOTALTALKTIME_graph\";\n"; - $JS_text.=" var TOTALWRAPTIME_graph=\"$mtd_TOTALWRAPTIME_graph\";\n"; - $JS_text.=" var TOTALCALLTIME_graph=\"$mtd_TOTALCALLTIME_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=10; i++) {\n"; - $JS_text.=" var cellID=\"MTD_graph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"MTD_graph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('MTD_stats_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $qtd_OFFERED_graph.=""._QXZ("TOTAL").":".trim($FtotCALLS).""; - $qtd_ANSWERED_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERS).""; - $qtd_AGENTS_graph.=""._QXZ("TOTAL").":".trim($FtotAGENTS).""; - $qtd_ABANDONED_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONS).""; - $qtd_ABANDONPCT_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONSpct)."%"; - $qtd_AVGABANDONTIME_graph.=""._QXZ("TOTAL").":".trim($FtotABANDONSavgTIME).""; - $qtd_AVGANSWERSPEED_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSavgspeedTIME).""; - $qtd_AVGTALKTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSavgTIME).""; - $qtd_TOTALTALKTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERStalkTIME).""; - $qtd_TOTALWRAPTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERSwrapTIME).""; - $qtd_TOTALCALLTIME_graph.=""._QXZ("TOTAL").":".trim($FtotANSWERStotTIME).""; - $JS_onload.="\tDrawQTDGraph('OFFERED', '1');\n"; - $JS_text.="function DrawQTDGraph(graph, th_id) {\n"; - $JS_text.=" var OFFERED_graph=\"$qtd_OFFERED_graph\";\n"; - $JS_text.=" var ANSWERED_graph=\"$qtd_ANSWERED_graph\";\n"; - $JS_text.=" var AGENTS_graph=\"$qtd_AGENTS_graph\";\n"; - $JS_text.=" var ABANDONED_graph=\"$qtd_ABANDONED_graph\";\n"; - $JS_text.=" var ABANDONPCT_graph=\"$qtd_ABANDONPCT_graph\";\n"; - $JS_text.=" var AVGABANDONTIME_graph=\"$qtd_AVGABANDONTIME_graph\";\n"; - $JS_text.=" var AVGANSWERSPEED_graph=\"$qtd_AVGANSWERSPEED_graph\";\n"; - $JS_text.=" var AVGTALKTIME_graph=\"$qtd_AVGTALKTIME_graph\";\n"; - $JS_text.=" var TOTALTALKTIME_graph=\"$qtd_TOTALTALKTIME_graph\";\n"; - $JS_text.=" var TOTALWRAPTIME_graph=\"$qtd_TOTALWRAPTIME_graph\";\n"; - $JS_text.=" var TOTALCALLTIME_graph=\"$qtd_TOTALCALLTIME_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=10; i++) {\n"; - $JS_text.=" var cellID=\"QTD_graph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"QTD_graph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('QTD_stats_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; + + $graph_count=count($graph_array); + $graph_title=_QXZ("DAILY REPORT")." - $query_date_BEGIN "._QXZ("to")." $query_date_END"; + include("graphcanvas.inc"); + $GRAPH=$graphCanvas; + $FtotAGENTS = sprintf("%8s", $FtotAGENTS); $ASCII_text.="$MAINH\n"; @@ -2079,7 +2141,7 @@ else if ($report_display_type=="HTML") { - $MAIN.=$JS_text.$GRAPH.$WTD_GRAPH.$MTD_GRAPH.$QTD_GRAPH; + $MAIN.=$GRAPH.$WTD_GRAPH.$MTD_GRAPH.$QTD_GRAPH.$JS_text; } else { diff --git a/agc_2-X/trunk/www/vicidial/AST_performance_comparison_report.php b/agc_2-X/trunk/www/vicidial/AST_performance_comparison_report.php index f385f49b..9236689e 100644 --- a/agc_2-X/trunk/www/vicidial/AST_performance_comparison_report.php +++ b/agc_2-X/trunk/www/vicidial/AST_performance_comparison_report.php @@ -14,6 +14,7 @@ # 150516-1314 - Fixed Javascript element problem, Issue #857 # 151227-1746 - Added option for searching archived data # 160121-2215 - Added report title header, default report format, cleaned up formatting +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -448,6 +449,9 @@ $HTML_head.=" \n"; $HTML_head.="\n"; $HTML_head.="\n"; $HTML_head.="\n"; +require("chart_button.php"); +$HTML_head.="\n"; +$HTML_head.="\n"; $HTML_head.="\n"; $HTML_head.=""._QXZ("$report_name")."\n"; @@ -638,35 +642,27 @@ else $ASCII_header2.="+-----------------+----------+"; $ASCII_header3.="|
"._QXZ("USER NAME",15)." | "._QXZ("ID",8)." |"; - $GRAPH="
\n"; - $GRAPH.=""; - $GRAPH2=""; + $master_graph_array=array(); for ($q=0; $q"._QXZ("CALLS").""; - $GRAPH2.=""; - $GRAPH2.=""; - $GRAPH2.=""; - $GRAPH2.=""; - $GRAPH2.=""; + $master_graph_array[$q]=array("APC_CALLSdata$rpt_date_numeric|1|CALLS|integer|", "APC_SALESdata$rpt_date_numeric|2|SALES|integer|", "APC_SALECONVdata$rpt_date_numeric|3|SALE CONV %|percent|", "APC_SPHdata$rpt_date_numeric|4|SALES PER HOUR|decimal|", "APC_TIMEdata$rpt_date_numeric|5|TIME|time|"); } $TOTALS_array[0]=_QXZ("TOTALS"); $graph_TOTALS_array[0]+=_QXZ("TOTALS"); - for ($q=0; $q"; - $CALLS_graph[$q]=$graph_header.""; - $SALES_graph[$q]=$graph_header.""; - $SALECONV_graph[$q]=$graph_header.""; - $SPH_graph[$q]=$graph_header.""; - $TIME_graph[$q]=$graph_header.""; ######### @@ -734,47 +724,87 @@ else } reset($agent_performance_array); - for ($j=0; $j"; - $SALES_graph[$q].=" "; - $SALECONV_graph[$q].=" "; - $SPH_graph[$q].=" "; - $TIME_graph[$q].=" "; + $multigraph_text=""; + $graph_id++; + $graph_array=$master_graph_array[$y]; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; } - $CALLS_graph[$q].=" "; - $SALES_graph[$q].=" "; - $SALECONV_graph[$q].=" "; - $SPH_graph[$q].=" "; - $TIME_graph[$q].=" "; + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $JS_text.="function DrawGraph(graph, th_id) {\n"; - $JS_onload.="\tDrawGraph('CALLS_".preg_replace('/[^0-9]/', '', $rpt_date_array[0])."', '1');\n"; - for ($q=0; $q\n"; $HTML_head.="\n"; $HTML_head.="\n"; +require("chart_button.php"); +$HTML_head.="\n"; +$HTML_head.="\n"; $HTML_head.="\n"; $HTML_head.=""._QXZ("$report_name")."$group_S\n"; @@ -657,30 +661,6 @@ if ( ($SUBMIT=="SUBMIT") or ($SUBMIT==_QXZ("SUBMIT")) ) $max_totalfirstcall=1; $max_totalavgsaletime=1; $max_totalavgcontacttime=1; - $TOTALGRAPH="

"._QXZ("PERFORMANCE SUMMARY")."
"._QXZ("SALES").""._QXZ("SALE CONV")." %"._QXZ("SALES PER HOUR").""._QXZ("TIME")."
USERS"._QXZ("CALLS")."
"._QXZ("SALES")."
"._QXZ("SALE CONV")." %
"._QXZ("SALES PER HOUR")."
"._QXZ("TIME")."
".$graph_stats[$j][1]."
".$graph_stats[$j][0]."".$graph_stats[$j][2]."
".$graph_stats[$j][0]."".$graph_stats[$j][3]."
".$graph_stats[$j][0]."".$graph_stats[$j][4]."
".$graph_stats[$j][0]."".sec_convert($graph_stats[$j][5], 'H')."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".$graph_TOTALS_array[($array_offset)]."
"._QXZ("TOTAL").":".$graph_TOTALS_array[($array_offset+1)]."
"._QXZ("TOTAL").":".$graph_TOTALS_array[($array_offset+2)]."
"._QXZ("TOTAL").":".$graph_TOTALS_array[($array_offset+3)]."
"._QXZ("TOTAL").":".sec_convert($graph_TOTALS_array[($array_offset+4)], 'H')."
"; - $TOTALGRAPH2="".$GRAPH2.""; - $TOTALGRAPH3="
"._QXZ("CALLS").""._QXZ("LEADS").""._QXZ("CONTACTS").""._QXZ("CONTACT RATIO").""._QXZ("SYSTEM TIME").""._QXZ("TALK TIME").""._QXZ("SALES").""._QXZ("SALES TO LEADS RATIO").""._QXZ("SALES TO CONTACTS RATIO").""._QXZ("SALES PER HOUR").""._QXZ("INCOMPLETE SALES").""._QXZ("CANCELLED SALES").""._QXZ("CALLBACKS").""._QXZ("FIRST CALLS").""._QXZ("AVG SALE TIME").""._QXZ("AVG CONTACT TIME")."

 


"; - $TOTALGRAPH_header=""; - $TOTALCALLS_graph=$TOTALGRAPH_header.""; - $TOTALLEADS_graph=$TOTALGRAPH_header.""; - $TOTALCONTACTS_graph=$TOTALGRAPH_header.""; - $TOTALCONTACTRATIO_graph=$TOTALGRAPH_header.""; - $TOTALSYSTEMTIME_graph=$TOTALGRAPH_header.""; - $TOTALTALKTIME_graph=$TOTALGRAPH_header.""; - $TOTALSALES_graph=$TOTALGRAPH_header.""; - $TOTALSALESLEADSRATIO_graph=$TOTALGRAPH_header.""; - $TOTALSALESCONTACTSRATIO_graph=$TOTALGRAPH_header.""; - $TOTALSALESPERHOUR_graph=$TOTALGRAPH_header.""; - $TOTALINCSALES_graph=$TOTALGRAPH_header.""; - $TOTALCANCELLEDSALES_graph=$TOTALGRAPH_header.""; - $TOTALCALLBACKS_graph=$TOTALGRAPH_header.""; - $TOTALFIRSTCALLS_graph=$TOTALGRAPH_header.""; - $TOTALAVGSALETIME_graph=$TOTALGRAPH_header.""; - $TOTALAVGCONTACTTIME_graph=$TOTALGRAPH_header.""; - for ($q=0; $q".$call_status[$q].""; - } for($i=0; $i<$user_group_ct; $i++) { @@ -740,29 +720,6 @@ if ( ($SUBMIT=="SUBMIT") or ($SUBMIT==_QXZ("SUBMIT")) ) $$max_varname=1; } - $GRAPH2="".$STATGRAPH.""; - $GRAPH3="
"._QXZ("CALL CENTER TOTAL")."
"._QXZ("USER").""._QXZ("CALLS")."
"._QXZ("LEADS")."
"._QXZ("CONTACTS")."
"._QXZ("CONTACT RATIO")."
"._QXZ("SYSTEM TIME")."
"._QXZ("TALK TIME")."
"._QXZ("SALES")."
"._QXZ("SALES TO LEADS RATIO")."
"._QXZ("SALES TO CONTACTS RATIO")."
"._QXZ("SALES PER HOUR")."
"._QXZ("INCOMPLETE SALES")."
"._QXZ("CANCELLED SALES")."
"._QXZ("CALLBACKS")."
"._QXZ("FIRST CALLS")."
"._QXZ("AVG SALE TIME")."
"._QXZ("AVG CONTACT TIME")."
"._QXZ("CALLS").""._QXZ("LEADS").""._QXZ("CONTACTS").""._QXZ("CONTACT RATIO").""._QXZ("SYSTEM TIME").""._QXZ("TALK TIME").""._QXZ("SALES").""._QXZ("SALES TO LEADS RATIO").""._QXZ("SALES TO CONTACTS RATIO").""._QXZ("SALES PER HOUR").""._QXZ("INCOMPLETE SALES").""._QXZ("CANCELLED SALES").""._QXZ("CALLBACKS").""._QXZ("FIRST CALLS").""._QXZ("AVG SALE TIME").""._QXZ("AVG CONTACT TIME")."

 


"; - $graph_header=""; - $CALLS_graph=$graph_header.""; - $LEADS_graph=$graph_header.""; - $CONTACTS_graph=$graph_header.""; - $CONTACTRATIO_graph=$graph_header.""; - $SYSTEMTIME_graph=$graph_header.""; - $TALKTIME_graph=$graph_header.""; - $SALES_graph=$graph_header.""; - $SALESLEADSRATIO_graph=$graph_header.""; - $SALESCONTACTSRATIO_graph=$graph_header.""; - $SALESPERHOUR_graph=$graph_header.""; - $INCSALES_graph=$graph_header.""; - $CANCELLEDSALES_graph=$graph_header.""; - $CALLBACKS_graph=$graph_header.""; - $FIRSTCALLS_graph=$graph_header.""; - $AVGSALETIME_graph=$graph_header.""; - $AVGCONTACTTIME_graph=$graph_header.""; - for ($q=0; $q".$call_status[$q].""; - } $j=0; $ASCII_text.="+------------------------------------------+------------+-------+-------+----------+---------------+---------------+-------------+-----------+-------+------------------------+----------------------+-------------------------+----------------+------------------+-----------------+-----------+-----------------------+-------------------+----------------------+$HTMLborderheader\n"; @@ -1028,91 +985,97 @@ if ( ($SUBMIT=="SUBMIT") or ($SUBMIT==_QXZ("SUBMIT")) ) $total_sales_talk_time+=$group_sales_talk_time; $total_contact_talk_time+=$group_contact_talk_time; - for ($d=1; $d<=count($graph_stats); $d++) { - if ($d==1) {$class=" first";} else if ($d==count($graph_stats)) {$class=" last";} else {$class="";} - $CALLS_graph.=" "; - $LEADS_graph.=" "; - $CONTACTS_graph.=" "; - $CONTACTRATIO_graph.=" "; - $SYSTEMTIME_graph.=" "; - $TALKTIME_graph.=" "; - $SALES_graph.=" "; - $SALESLEADSRATIO_graph.=" "; - $SALESCONTACTSRATIO_graph.=" "; - $SALESPERHOUR_graph.=" "; - $INCSALES_graph.=" "; - $CANCELLEDSALES_graph.=" "; - $CALLBACKS_graph.=" "; - $FIRSTCALLS_graph.=" "; - $AVGSALETIME_graph.=" "; - $AVGCONTACTTIME_graph.=" "; - for ($e=0; $e\n"; - - $$varname.=" "; + # USE THIS FOR COMBINED graphs, use pipe-delimited array elements, dataset_name|index|link_name|graph_override + # You have to hard code the graph name in where it is overridden and mind the data indices. No other way to do it. + $multigraph_text=""; + $graph_id++; + $graph_array=array("ATPD_CALLSdata|1|CALLS|integer|", "ATPD_LEADSdata|2|LEADS|integer|", "ATPD_CONTACTSdata|3|CONTACTS|integer|", "ATPD_CONTACTRATIOdata|4|CONTACT RATIO|percent|", "ATPD_SYSTEMTIMEdata|5|SYSTEM TIME|time|", "ATPD_TALKTIMEdata|6|TALK TIME|time|", "ATPD_SALESdata|7|SALES|integer|", "ATPD_SALESTOLEADSdata|8|SALES TO LEADS RATIO|decimal|", "ATPD_SALESTOCONTACTSdata|9|SALES TO CONTACTS RATIO|decimal|", "ATPD_SALESPERHOURdata|10|SALES PER HOUR|decimal|", "ATPD_INCOMPLETESALESSdata|11|INCOMPLETE SALES|integer|", "ATPD_CANCELLEDSALESdata|12|CANCELLED SALES|integer|", "ATPD_CALLBACKSdata|13|CALLBACKS|integer|", "ATPD_FIRSTCALLSdata|14|FIRST CALLS|decimal|", "ATPD_AVGSALETIMEdata|15|AVG SALE TIME|time|", "ATPD_AVGCONTACTTIMEdata|16|AVG CONTACT TIME|time|"); + + for ($e=0; $e"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $CALLS_graph.="
"._QXZ("TEAM").": $user_group[$i] - $group_name
"._QXZ("USER").""._QXZ("CALLS")."
"._QXZ("LEADS")."
"._QXZ("CONTACTS")."
"._QXZ("CONTACT RATIO")."
"._QXZ("SYSTEM TIME")."
"._QXZ("TALK TIME")."
"._QXZ("SALES")."
"._QXZ("SALES TO LEADS RATIO")."
"._QXZ("SALES TO CONTACTS RATIO")."
"._QXZ("SALES PER HOUR")."
"._QXZ("INCOMPLETE SALES")."
"._QXZ("CANCELLED SALES")."
"._QXZ("CALLBACKS")."
"._QXZ("FIRST CALLS")."
"._QXZ("AVG SALE TIME")."
"._QXZ("AVG CONTACT TIME")."
".$graph_stats[$d][0]."".$graph_stats[$d][1]."
".$graph_stats[$d][0]."".$graph_stats[$d][2]."
".$graph_stats[$d][0]."".$graph_stats[$d][3]."
".$graph_stats[$d][0]."".$graph_stats[$d][4]."%
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][5], 'H')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][6], 'H')."
".$graph_stats[$d][0]."".$graph_stats[$d][7]."
".$graph_stats[$d][0]."".$graph_stats[$d][8]."%
".$graph_stats[$d][0]."".$graph_stats[$d][9]."%
".$graph_stats[$d][0]."".$graph_stats[$d][10]."
".$graph_stats[$d][0]."".$graph_stats[$d][11]."
".$graph_stats[$d][0]."".$graph_stats[$d][12]."
".$graph_stats[$d][0]."".$graph_stats[$d][13]."
".$graph_stats[$d][0]."".$graph_stats[$d][14]."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][15], 'H')."
".$graph_stats[$d][0]."".sec_convert($graph_stats[$d][16], 'H')."
".$graph_stats[$d][0]."".$graph_stats[$d][($e+17)]."
"._QXZ("TOTAL").": $current_graph_total
"._QXZ("TOTAL").":".trim($group_calls)."
"; - $LEADS_graph.=""._QXZ("TOTAL").":".trim($group_leads).""; - $CONTACTS_graph.=""._QXZ("TOTAL").":".trim($group_contacts).""; - $CONTACTRATIO_graph.=""._QXZ("TOTAL").":".trim($group_contact_ratio)."%"; - $SYSTEMTIME_graph.=""._QXZ("TOTAL").":".sec_convert($group_system_time,'H').""; - $TALKTIME_graph.=""._QXZ("TOTAL").":".sec_convert($group_talk_time,'H').""; - $SALES_graph.=""._QXZ("TOTAL").":".trim($group_sales).""; - $SALESLEADSRATIO_graph.=""._QXZ("TOTAL").":".trim($group_sales_ratio)."%"; - $SALESCONTACTSRATIO_graph.=""._QXZ("TOTAL").":".trim($group_sale_contact_ratio)."%"; - $SALESPERHOUR_graph.=""._QXZ("TOTAL").":".trim($group_sales_per_hour).""; - $INCSALES_graph.=""._QXZ("TOTAL").":".trim($group_inc_sales).""; - $CANCELLEDSALES_graph.=""._QXZ("TOTAL").":".trim($group_cnc_sales).""; - $CALLBACKS_graph.=""._QXZ("TOTAL").":".trim($group_callbacks).""; - $FIRSTCALLS_graph.=""._QXZ("TOTAL").":".trim($group_stcall).""; - $AVGSALETIME_graph.=""._QXZ("TOTAL").":".trim($group_average_sale_time).""; - $AVGCONTACTTIME_graph.=""._QXZ("TOTAL").":".trim($group_average_contact_time).""; - for ($e=0; $e".trim($$total_var).""; - } - $JS_onload.="\tDraw".$user_group[$i]."Graph('CALLS', '1');\n"; - $JS_text.="function Draw".$user_group[$i]."Graph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$CALLS_graph\";\n"; - $JS_text.=" var LEADS_graph=\"$LEADS_graph\";\n"; - $JS_text.=" var CONTACTS_graph=\"$CONTACTS_graph\";\n"; - $JS_text.=" var CONTACTRATIO_graph=\"$CONTACTRATIO_graph\";\n"; - $JS_text.=" var SYSTEMTIME_graph=\"$SYSTEMTIME_graph\";\n"; - $JS_text.=" var TALKTIME_graph=\"$TALKTIME_graph\";\n"; - $JS_text.=" var SALES_graph=\"$SALES_graph\";\n"; - $JS_text.=" var SALESLEADSRATIO_graph=\"$SALESLEADSRATIO_graph\";\n"; - $JS_text.=" var SALESCONTACTSRATIO_graph=\"$SALESCONTACTSRATIO_graph\";\n"; - $JS_text.=" var SALESPERHOUR_graph=\"$SALESPERHOUR_graph\";\n"; - $JS_text.=" var INCSALES_graph=\"$INCSALES_graph\";\n"; - $JS_text.=" var CANCELLEDSALES_graph=\"$CANCELLEDSALES_graph\";\n"; - $JS_text.=" var CALLBACKS_graph=\"$CALLBACKS_graph\";\n"; - $JS_text.=" var FIRSTCALLS_graph=\"$FIRSTCALLS_graph\";\n"; - $JS_text.=" var AVGSALETIME_graph=\"$AVGSALETIME_graph\";\n"; - $JS_text.=" var AVGCONTACTTIME_graph=\"$AVGCONTACTTIME_graph\";\n"; - $JS_text.="\n"; - for ($e=0; $e".$total_graph_stats[$d][1].""; - $TOTALLEADS_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][2].""; - $TOTALCONTACTS_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][3].""; - $TOTALCONTACTRATIO_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][4]."%"; - $TOTALSYSTEMTIME_graph.=" ".$total_graph_stats[$d][0]."".sec_convert($total_graph_stats[$d][5], 'H').""; - $TOTALTALKTIME_graph.=" ".$total_graph_stats[$d][0]."".sec_convert($total_graph_stats[$d][6], 'H').""; - $TOTALSALES_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][7].""; - $TOTALSALESLEADSRATIO_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][8]."%"; - $TOTALSALESCONTACTSRATIO_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][9]."%"; - $TOTALSALESPERHOUR_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][10].""; - $TOTALINCSALES_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][11].""; - $TOTALCANCELLEDSALES_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][12].""; - $TOTALCALLBACKS_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][13].""; - $TOTALFIRSTCALLS_graph.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][14].""; - $TOTALAVGSALETIME_graph.=" ".$total_graph_stats[$d][0]."".sec_convert($total_graph_stats[$d][15], 'H').""; - $TOTALAVGCONTACTTIME_graph.=" ".$total_graph_stats[$d][0]."".sec_convert($total_graph_stats[$d][16], 'H').""; - for ($e=0; $e\n"; - - $$varname.=" ".$total_graph_stats[$d][0]."".$total_graph_stats[$d][($e+17)].""; + # USE THIS FOR COMBINED graphs, use pipe-delimited array elements, dataset_name|index|link_name|graph_override + # You have to hard code the graph name in where it is overridden and mind the data indices. No other way to do it. + $multigraph_text=""; + $graph_id++; + $graph_array=array("ATPD_TOTALCALLSdata|1|CALLS|integer|", "ATPD_TOTALLEADSdata|2|LEADS|integer|", "ATPD_TOTALCONTACTSdata|3|CONTACTS|integer|", "ATPD_TOTALCONTACTRATIOdata|4|CONTACT RATIO|decimal|", "ATPD_TOTALSYSTEMTIMEdata|5|SYSTEM TIME|time|", "ATPD_TOTALTALKTIMEdata|6|TALK TIME|time|", "ATPD_TOTALSALESdata|7|SALES|integer|", "ATPD_TOTALSALESTOLEADSdata|8|SALES TO LEADS RATIO|decimal|", "ATPD_TOTALSALESTOCONTACTSdata|9|SALES TO CONTACTS RATIO|decimal|", "ATPD_TOTALSALESPERHOURdata|10|SALES PER HOUR|decimal|", "ATPD_TOTALINCOMPLETESALESSdata|11|INCOMPLETE SALES|integer|", "ATPD_TOTALCANCELLEDSALESdata|12|CANCELLED SALES|integer|", "ATPD_TOTALCALLBACKSdata|13|CALLBACKS|integer|", "ATPD_TOTALFIRSTCALLSdata|14|FIRST CALLS|decimal|", "ATPD_TOTALAVGSALETIMEdata|15|AVG SALE TIME|time|", "ATPD_TOTALAVGCONTACTTIMEdata|16|AVG CONTACT TIME|time|"); + + for ($e=0; $e"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" "._QXZ("TOTAL").": $current_graph_total\n"; + $chart_options="options: { legend: { display: false }},"; + break; } + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $TOTALCALLS_graph.=""._QXZ("TOTAL").":".trim($total_calls).""; - $TOTALLEADS_graph.=""._QXZ("TOTAL").":".trim($total_leads).""; - $TOTALCONTACTS_graph.=""._QXZ("TOTAL").":".trim($total_contacts).""; - $TOTALCONTACTRATIO_graph.=""._QXZ("TOTAL").":".trim($total_contact_ratio)."%"; - $TOTALSYSTEMTIME_graph.=""._QXZ("TOTAL").":".sec_convert($total_system_time,'H').""; - $TOTALTALKTIME_graph.=""._QXZ("TOTAL").":".sec_convert($total_talk_time,'H').""; - $TOTALSALES_graph.=""._QXZ("TOTAL").":".trim($total_sales).""; - $TOTALSALESLEADSRATIO_graph.=""._QXZ("TOTAL").":".trim($total_sales_ratio)."%"; - $TOTALSALESCONTACTSRATIO_graph.=""._QXZ("TOTAL").":".trim($total_sale_contact_ratio)."%"; - $TOTALSALESPERHOUR_graph.=""._QXZ("TOTAL").":".trim($total_sales_per_hour).""; - $TOTALINCSALES_graph.=""._QXZ("TOTAL").":".trim($total_inc_sales).""; - $TOTALCANCELLEDSALES_graph.=""._QXZ("TOTAL").":".trim($total_cnc_sales).""; - $TOTALCALLBACKS_graph.=""._QXZ("TOTAL").":".trim($total_callbacks).""; - $TOTALFIRSTCALLS_graph.=""._QXZ("TOTAL").":".trim($total_stcall).""; - $TOTALAVGSALETIME_graph.=""._QXZ("TOTAL").":".trim($total_average_sale_time).""; - $TOTALAVGCONTACTTIME_graph.=""._QXZ("TOTAL").":".trim($total_average_contact_time).""; - for ($e=0; $e".trim($$total_var).""; - } - $JS_onload.="\tDrawTotalGraph('CALLS', '1');\n"; - $JS_text.="function DrawTotalGraph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$TOTALCALLS_graph\";\n"; - $JS_text.=" var LEADS_graph=\"$TOTALLEADS_graph\";\n"; - $JS_text.=" var CONTACTS_graph=\"$TOTALCONTACTS_graph\";\n"; - $JS_text.=" var CONTACTRATIO_graph=\"$TOTALCONTACTRATIO_graph\";\n"; - $JS_text.=" var SYSTEMTIME_graph=\"$TOTALSYSTEMTIME_graph\";\n"; - $JS_text.=" var TALKTIME_graph=\"$TOTALTALKTIME_graph\";\n"; - $JS_text.=" var SALES_graph=\"$TOTALSALES_graph\";\n"; - $JS_text.=" var SALESLEADSRATIO_graph=\"$TOTALSALESLEADSRATIO_graph\";\n"; - $JS_text.=" var SALESCONTACTSRATIO_graph=\"$TOTALSALESCONTACTSRATIO_graph\";\n"; - $JS_text.=" var SALESPERHOUR_graph=\"$TOTALSALESPERHOUR_graph\";\n"; - $JS_text.=" var INCSALES_graph=\"$TOTALINCSALES_graph\";\n"; - $JS_text.=" var CANCELLEDSALES_graph=\"$TOTALCANCELLEDSALES_graph\";\n"; - $JS_text.=" var CALLBACKS_graph=\"$TOTALCALLBACKS_graph\";\n"; - $JS_text.=" var FIRSTCALLS_graph=\"$TOTALFIRSTCALLS_graph\";\n"; - $JS_text.=" var AVGSALETIME_graph=\"$TOTALAVGSALETIME_graph\";\n"; - $JS_text.=" var AVGCONTACTTIME_graph=\"$TOTALAVGCONTACTTIME_graph\";\n"; - for ($e=0; $e lum2) { + return (lum1 + 0.05) / (lum2 + 0.05); + } + return (lum2 + 0.05) / (lum1 + 0.05); + }, + + level: function (color2) { + var contrastRatio = this.contrast(color2); + if (contrastRatio >= 7.1) { + return 'AAA'; + } + + return (contrastRatio >= 4.5) ? 'AA' : ''; + }, + + dark: function () { + // YIQ equation from http://24ways.org/2010/calculating-color-contrast + var rgb = this.values.rgb; + var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; + return yiq < 128; + }, + + light: function () { + return !this.dark(); + }, + + negate: function () { + var rgb = []; + for (var i = 0; i < 3; i++) { + rgb[i] = 255 - this.values.rgb[i]; + } + this.setValues('rgb', rgb); + return this; + }, + + lighten: function (ratio) { + var hsl = this.values.hsl; + hsl[2] += hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + darken: function (ratio) { + var hsl = this.values.hsl; + hsl[2] -= hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + saturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] += hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + desaturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] -= hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + whiten: function (ratio) { + var hwb = this.values.hwb; + hwb[1] += hwb[1] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + blacken: function (ratio) { + var hwb = this.values.hwb; + hwb[2] += hwb[2] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + greyscale: function () { + var rgb = this.values.rgb; + // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale + var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; + this.setValues('rgb', [val, val, val]); + return this; + }, + + clearer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha - (alpha * ratio)); + return this; + }, + + opaquer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha + (alpha * ratio)); + return this; + }, + + rotate: function (degrees) { + var hsl = this.values.hsl; + var hue = (hsl[0] + degrees) % 360; + hsl[0] = hue < 0 ? 360 + hue : hue; + this.setValues('hsl', hsl); + return this; + }, + + /** + * Ported from sass implementation in C + * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 + */ + mix: function (mixinColor, weight) { + var color1 = this; + var color2 = mixinColor; + var p = weight === undefined ? 0.5 : weight; + + var w = 2 * p - 1; + var a = color1.alpha() - color2.alpha(); + + var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + + return this + .rgb( + w1 * color1.red() + w2 * color2.red(), + w1 * color1.green() + w2 * color2.green(), + w1 * color1.blue() + w2 * color2.blue() + ) + .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); + }, + + toJSON: function () { + return this.rgb(); + }, + + clone: function () { + // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, + // making the final build way to big to embed in Chart.js. So let's do it manually, + // assuming that values to clone are 1 dimension arrays containing only numbers, + // except 'alpha' which is a number. + var result = new Color(); + var source = this.values; + var target = result.values; + var value, type; + + for (var prop in source) { + if (source.hasOwnProperty(prop)) { + value = source[prop]; + type = ({}).toString.call(value); + if (type === '[object Array]') { + target[prop] = value.slice(0); + } else if (type === '[object Number]') { + target[prop] = value; + } else { + console.error('unexpected color value:', value); + } + } + } + + return result; + } +}; + +Color.prototype.spaces = { + rgb: ['red', 'green', 'blue'], + hsl: ['hue', 'saturation', 'lightness'], + hsv: ['hue', 'saturation', 'value'], + hwb: ['hue', 'whiteness', 'blackness'], + cmyk: ['cyan', 'magenta', 'yellow', 'black'] +}; + +Color.prototype.maxes = { + rgb: [255, 255, 255], + hsl: [360, 100, 100], + hsv: [360, 100, 100], + hwb: [360, 100, 100], + cmyk: [100, 100, 100, 100] +}; + +Color.prototype.getValues = function (space) { + var values = this.values; + var vals = {}; + + for (var i = 0; i < space.length; i++) { + vals[space.charAt(i)] = values[space][i]; + } + + if (values.alpha !== 1) { + vals.a = values.alpha; + } + + // {r: 255, g: 255, b: 255, a: 0.4} + return vals; +}; + +Color.prototype.setValues = function (space, vals) { + var values = this.values; + var spaces = this.spaces; + var maxes = this.maxes; + var alpha = 1; + var i; + + if (space === 'alpha') { + alpha = vals; + } else if (vals.length) { + // [10, 10, 10] + values[space] = vals.slice(0, space.length); + alpha = vals[space.length]; + } else if (vals[space.charAt(0)] !== undefined) { + // {r: 10, g: 10, b: 10} + for (i = 0; i < space.length; i++) { + values[space][i] = vals[space.charAt(i)]; + } + + alpha = vals.a; + } else if (vals[spaces[space][0]] !== undefined) { + // {red: 10, green: 10, blue: 10} + var chans = spaces[space]; + + for (i = 0; i < space.length; i++) { + values[space][i] = vals[chans[i]]; + } + + alpha = vals.alpha; + } + + values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); + + if (space === 'alpha') { + return false; + } + + var capped; + + // cap values of the space prior converting all values + for (i = 0; i < space.length; i++) { + capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); + values[space][i] = Math.round(capped); + } + + // convert to all the other color spaces + for (var sname in spaces) { + if (sname !== space) { + values[sname] = convert[space][sname](values[space]); + } + } + + return true; +}; + +Color.prototype.setSpace = function (space, args) { + var vals = args[0]; + + if (vals === undefined) { + // color.rgb() + return this.getValues(space); + } + + // color.rgb(10, 10, 10) + if (typeof vals === 'number') { + vals = Array.prototype.slice.call(args); + } + + this.setValues(space, vals); + return this; +}; + +Color.prototype.setChannel = function (space, index, val) { + var svalues = this.values[space]; + if (val === undefined) { + // color.red() + return svalues[index]; + } else if (val === svalues[index]) { + // color.red(color.red()) + return this; + } + + // color.red(100) + svalues[index] = val; + this.setValues(space, svalues); + + return this; +}; + +if (typeof window !== 'undefined') { + window.Color = Color; +} + +module.exports = Color; + +},{"2":2,"5":5}],4:[function(require,module,exports){ +/* MIT license */ + +module.exports = { + rgb2hsl: rgb2hsl, + rgb2hsv: rgb2hsv, + rgb2hwb: rgb2hwb, + rgb2cmyk: rgb2cmyk, + rgb2keyword: rgb2keyword, + rgb2xyz: rgb2xyz, + rgb2lab: rgb2lab, + rgb2lch: rgb2lch, + + hsl2rgb: hsl2rgb, + hsl2hsv: hsl2hsv, + hsl2hwb: hsl2hwb, + hsl2cmyk: hsl2cmyk, + hsl2keyword: hsl2keyword, + + hsv2rgb: hsv2rgb, + hsv2hsl: hsv2hsl, + hsv2hwb: hsv2hwb, + hsv2cmyk: hsv2cmyk, + hsv2keyword: hsv2keyword, + + hwb2rgb: hwb2rgb, + hwb2hsl: hwb2hsl, + hwb2hsv: hwb2hsv, + hwb2cmyk: hwb2cmyk, + hwb2keyword: hwb2keyword, + + cmyk2rgb: cmyk2rgb, + cmyk2hsl: cmyk2hsl, + cmyk2hsv: cmyk2hsv, + cmyk2hwb: cmyk2hwb, + cmyk2keyword: cmyk2keyword, + + keyword2rgb: keyword2rgb, + keyword2hsl: keyword2hsl, + keyword2hsv: keyword2hsv, + keyword2hwb: keyword2hwb, + keyword2cmyk: keyword2cmyk, + keyword2lab: keyword2lab, + keyword2xyz: keyword2xyz, + + xyz2rgb: xyz2rgb, + xyz2lab: xyz2lab, + xyz2lch: xyz2lch, + + lab2xyz: lab2xyz, + lab2rgb: lab2rgb, + lab2lch: lab2lch, + + lch2lab: lch2lab, + lch2xyz: lch2xyz, + lch2rgb: lch2rgb +} + + +function rgb2hsl(rgb) { + var r = rgb[0]/255, + g = rgb[1]/255, + b = rgb[2]/255, + min = Math.min(r, g, b), + max = Math.max(r, g, b), + delta = max - min, + h, s, l; + + if (max == min) + h = 0; + else if (r == max) + h = (g - b) / delta; + else if (g == max) + h = 2 + (b - r) / delta; + else if (b == max) + h = 4 + (r - g)/ delta; + + h = Math.min(h * 60, 360); + + if (h < 0) + h += 360; + + l = (min + max) / 2; + + if (max == min) + s = 0; + else if (l <= 0.5) + s = delta / (max + min); + else + s = delta / (2 - max - min); + + return [h, s * 100, l * 100]; +} + +function rgb2hsv(rgb) { + var r = rgb[0], + g = rgb[1], + b = rgb[2], + min = Math.min(r, g, b), + max = Math.max(r, g, b), + delta = max - min, + h, s, v; + + if (max == 0) + s = 0; + else + s = (delta/max * 1000)/10; + + if (max == min) + h = 0; + else if (r == max) + h = (g - b) / delta; + else if (g == max) + h = 2 + (b - r) / delta; + else if (b == max) + h = 4 + (r - g) / delta; + + h = Math.min(h * 60, 360); + + if (h < 0) + h += 360; + + v = ((max / 255) * 1000) / 10; + + return [h, s, v]; +} + +function rgb2hwb(rgb) { + var r = rgb[0], + g = rgb[1], + b = rgb[2], + h = rgb2hsl(rgb)[0], + w = 1/255 * Math.min(r, Math.min(g, b)), + b = 1 - 1/255 * Math.max(r, Math.max(g, b)); + + return [h, w * 100, b * 100]; +} + +function rgb2cmyk(rgb) { + var r = rgb[0] / 255, + g = rgb[1] / 255, + b = rgb[2] / 255, + c, m, y, k; + + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; + return [c * 100, m * 100, y * 100, k * 100]; +} + +function rgb2keyword(rgb) { + return reverseKeywords[JSON.stringify(rgb)]; +} + +function rgb2xyz(rgb) { + var r = rgb[0] / 255, + g = rgb[1] / 255, + b = rgb[2] / 255; + + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); + + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); + + return [x * 100, y *100, z * 100]; +} + +function rgb2lab(rgb) { + var xyz = rgb2xyz(rgb), + x = xyz[0], + y = xyz[1], + z = xyz[2], + l, a, b; + + x /= 95.047; + y /= 100; + z /= 108.883; + + x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); + + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + + return [l, a, b]; +} + +function rgb2lch(args) { + return lab2lch(rgb2lab(args)); +} + +function hsl2rgb(hsl) { + var h = hsl[0] / 360, + s = hsl[1] / 100, + l = hsl[2] / 100, + t1, t2, t3, rgb, val; + + if (s == 0) { + val = l * 255; + return [val, val, val]; + } + + if (l < 0.5) + t2 = l * (1 + s); + else + t2 = l + s - l * s; + t1 = 2 * l - t2; + + rgb = [0, 0, 0]; + for (var i = 0; i < 3; i++) { + t3 = h + 1 / 3 * - (i - 1); + t3 < 0 && t3++; + t3 > 1 && t3--; + + if (6 * t3 < 1) + val = t1 + (t2 - t1) * 6 * t3; + else if (2 * t3 < 1) + val = t2; + else if (3 * t3 < 2) + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + else + val = t1; + + rgb[i] = val * 255; + } + + return rgb; +} + +function hsl2hsv(hsl) { + var h = hsl[0], + s = hsl[1] / 100, + l = hsl[2] / 100, + sv, v; + + if(l === 0) { + // no need to do calc on black + // also avoids divide by 0 error + return [0, 0, 0]; + } + + l *= 2; + s *= (l <= 1) ? l : 2 - l; + v = (l + s) / 2; + sv = (2 * s) / (l + s); + return [h, sv * 100, v * 100]; +} + +function hsl2hwb(args) { + return rgb2hwb(hsl2rgb(args)); +} + +function hsl2cmyk(args) { + return rgb2cmyk(hsl2rgb(args)); +} + +function hsl2keyword(args) { + return rgb2keyword(hsl2rgb(args)); +} + + +function hsv2rgb(hsv) { + var h = hsv[0] / 60, + s = hsv[1] / 100, + v = hsv[2] / 100, + hi = Math.floor(h) % 6; + + var f = h - Math.floor(h), + p = 255 * v * (1 - s), + q = 255 * v * (1 - (s * f)), + t = 255 * v * (1 - (s * (1 - f))), + v = 255 * v; + + switch(hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +} + +function hsv2hsl(hsv) { + var h = hsv[0], + s = hsv[1] / 100, + v = hsv[2] / 100, + sl, l; + + l = (2 - s) * v; + sl = s * v; + sl /= (l <= 1) ? l : 2 - l; + sl = sl || 0; + l /= 2; + return [h, sl * 100, l * 100]; +} + +function hsv2hwb(args) { + return rgb2hwb(hsv2rgb(args)) +} + +function hsv2cmyk(args) { + return rgb2cmyk(hsv2rgb(args)); +} + +function hsv2keyword(args) { + return rgb2keyword(hsv2rgb(args)); +} + +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +function hwb2rgb(hwb) { + var h = hwb[0] / 360, + wh = hwb[1] / 100, + bl = hwb[2] / 100, + ratio = wh + bl, + i, v, f, n; + + // wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } + + i = Math.floor(6 * h); + v = 1 - bl; + f = 6 * h - i; + if ((i & 0x01) != 0) { + f = 1 - f; + } + n = wh + f * (v - wh); // linear interpolation + + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; + } + + return [r * 255, g * 255, b * 255]; +} + +function hwb2hsl(args) { + return rgb2hsl(hwb2rgb(args)); +} + +function hwb2hsv(args) { + return rgb2hsv(hwb2rgb(args)); +} + +function hwb2cmyk(args) { + return rgb2cmyk(hwb2rgb(args)); +} + +function hwb2keyword(args) { + return rgb2keyword(hwb2rgb(args)); +} + +function cmyk2rgb(cmyk) { + var c = cmyk[0] / 100, + m = cmyk[1] / 100, + y = cmyk[2] / 100, + k = cmyk[3] / 100, + r, g, b; + + r = 1 - Math.min(1, c * (1 - k) + k); + g = 1 - Math.min(1, m * (1 - k) + k); + b = 1 - Math.min(1, y * (1 - k) + k); + return [r * 255, g * 255, b * 255]; +} + +function cmyk2hsl(args) { + return rgb2hsl(cmyk2rgb(args)); +} + +function cmyk2hsv(args) { + return rgb2hsv(cmyk2rgb(args)); +} + +function cmyk2hwb(args) { + return rgb2hwb(cmyk2rgb(args)); +} + +function cmyk2keyword(args) { + return rgb2keyword(cmyk2rgb(args)); +} + + +function xyz2rgb(xyz) { + var x = xyz[0] / 100, + y = xyz[1] / 100, + z = xyz[2] / 100, + r, g, b; + + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); + + // assume sRGB + r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + : r = (r * 12.92); + + g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g = (g * 12.92); + + b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : b = (b * 12.92); + + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); + + return [r * 255, g * 255, b * 255]; +} + +function xyz2lab(xyz) { + var x = xyz[0], + y = xyz[1], + z = xyz[2], + l, a, b; + + x /= 95.047; + y /= 100; + z /= 108.883; + + x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); + + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + + return [l, a, b]; +} + +function xyz2lch(args) { + return lab2lch(xyz2lab(args)); +} + +function lab2xyz(lab) { + var l = lab[0], + a = lab[1], + b = lab[2], + x, y, z, y2; + + if (l <= 8) { + y = (l * 100) / 903.3; + y2 = (7.787 * (y / 100)) + (16 / 116); + } else { + y = 100 * Math.pow((l + 16) / 116, 3); + y2 = Math.pow(y / 100, 1/3); + } + + x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3); + + z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3); + + return [x, y, z]; +} + +function lab2lch(lab) { + var l = lab[0], + a = lab[1], + b = lab[2], + hr, h, c; + + hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; + if (h < 0) { + h += 360; + } + c = Math.sqrt(a * a + b * b); + return [l, c, h]; +} + +function lab2rgb(args) { + return xyz2rgb(lab2xyz(args)); +} + +function lch2lab(lch) { + var l = lch[0], + c = lch[1], + h = lch[2], + a, b, hr; + + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); + return [l, a, b]; +} + +function lch2xyz(args) { + return lab2xyz(lch2lab(args)); +} + +function lch2rgb(args) { + return lab2rgb(lch2lab(args)); +} + +function keyword2rgb(keyword) { + return cssKeywords[keyword]; +} + +function keyword2hsl(args) { + return rgb2hsl(keyword2rgb(args)); +} + +function keyword2hsv(args) { + return rgb2hsv(keyword2rgb(args)); +} + +function keyword2hwb(args) { + return rgb2hwb(keyword2rgb(args)); +} + +function keyword2cmyk(args) { + return rgb2cmyk(keyword2rgb(args)); +} + +function keyword2lab(args) { + return rgb2lab(keyword2rgb(args)); +} + +function keyword2xyz(args) { + return rgb2xyz(keyword2rgb(args)); +} + +var cssKeywords = { + 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] +}; + +var reverseKeywords = {}; +for (var key in cssKeywords) { + reverseKeywords[JSON.stringify(cssKeywords[key])] = key; +} + +},{}],5:[function(require,module,exports){ +var conversions = require(4); + +var convert = function() { + return new Converter(); +} + +for (var func in conversions) { + // export Raw versions + convert[func + "Raw"] = (function(func) { + // accept array or plain args + return function(arg) { + if (typeof arg == "number") + arg = Array.prototype.slice.call(arguments); + return conversions[func](arg); + } + })(func); + + var pair = /(\w+)2(\w+)/.exec(func), + from = pair[1], + to = pair[2]; + + // export rgb2hsl and ["rgb"]["hsl"] + convert[from] = convert[from] || {}; + + convert[from][to] = convert[func] = (function(func) { + return function(arg) { + if (typeof arg == "number") + arg = Array.prototype.slice.call(arguments); + + var val = conversions[func](arg); + if (typeof val == "string" || val === undefined) + return val; // keyword + + for (var i = 0; i < val.length; i++) + val[i] = Math.round(val[i]); + return val; + } + })(func); +} + + +/* Converter does lazy conversion and caching */ +var Converter = function() { + this.convs = {}; +}; + +/* Either get the values for a space or + set the values for a space, depending on args */ +Converter.prototype.routeSpace = function(space, args) { + var values = args[0]; + if (values === undefined) { + // color.rgb() + return this.getValues(space); + } + // color.rgb(10, 10, 10) + if (typeof values == "number") { + values = Array.prototype.slice.call(args); + } + + return this.setValues(space, values); +}; + +/* Set the values for a space, invalidating cache */ +Converter.prototype.setValues = function(space, values) { + this.space = space; + this.convs = {}; + this.convs[space] = values; + return this; +}; + +/* Get the values for a space. If there's already + a conversion for the space, fetch it, otherwise + compute it */ +Converter.prototype.getValues = function(space) { + var vals = this.convs[space]; + if (!vals) { + var fspace = this.space, + from = this.convs[fspace]; + vals = convert[fspace][space](from); + + this.convs[space] = vals; + } + return vals; +}; + +["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) { + Converter.prototype[space] = function(vals) { + return this.routeSpace(space, arguments); + } +}); + +module.exports = convert; +},{"4":4}],6:[function(require,module,exports){ +module.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] +}; +},{}],7:[function(require,module,exports){ +/** + * @namespace Chart + */ +var Chart = require(26)(); + +require(25)(Chart); +require(24)(Chart); +require(21)(Chart); +require(22)(Chart); +require(23)(Chart); +require(27)(Chart); +require(31)(Chart); +require(29)(Chart); +require(30)(Chart); +require(32)(Chart); +require(28)(Chart); +require(33)(Chart); + +require(34)(Chart); +require(35)(Chart); +require(36)(Chart); +require(37)(Chart); + +require(40)(Chart); +require(38)(Chart); +require(39)(Chart); +require(41)(Chart); +require(42)(Chart); +require(43)(Chart); + +// Controllers must be loaded after elements +// See Chart.core.datasetController.dataElementType +require(15)(Chart); +require(16)(Chart); +require(17)(Chart); +require(18)(Chart); +require(19)(Chart); +require(20)(Chart); + +require(8)(Chart); +require(9)(Chart); +require(10)(Chart); +require(11)(Chart); +require(12)(Chart); +require(13)(Chart); +require(14)(Chart); + +window.Chart = module.exports = Chart; + +},{"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,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"8":8,"9":9}],8:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + Chart.Bar = function(context, config) { + config.type = 'bar'; + + return new Chart(context, config); + }; + +}; +},{}],9:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + Chart.Bubble = function(context, config) { + config.type = 'bubble'; + return new Chart(context, config); + }; + +}; +},{}],10:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + Chart.Doughnut = function(context, config) { + config.type = 'doughnut'; + + return new Chart(context, config); + }; + +}; +},{}],11:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + Chart.Line = function(context, config) { + config.type = 'line'; + + return new Chart(context, config); + }; + +}; +},{}],12:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + Chart.PolarArea = function(context, config) { + config.type = 'polarArea'; + + return new Chart(context, config); + }; + +}; +},{}],13:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + Chart.Radar = function(context, config) { + config.options = Chart.helpers.configMerge({ aspectRatio: 1 }, config.options); + config.type = 'radar'; + + return new Chart(context, config); + }; + +}; + +},{}],14:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + var defaultConfig = { + hover: { + mode: 'single' + }, + + scales: { + xAxes: [{ + type: "linear", // scatter should not use a category axis + position: "bottom", + id: "x-axis-1" // need an ID so datasets can reference the scale + }], + yAxes: [{ + type: "linear", + position: "left", + id: "y-axis-1" + }] + }, + + tooltips: { + callbacks: { + title: function(tooltipItems, data) { + // Title doesn't make sense for scatter since we format the data as a point + return ''; + }, + label: function(tooltipItem, data) { + return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')'; + } + } + } + }; + + // Register the default config for this type + Chart.defaults.scatter = defaultConfig; + + // Scatter charts use line controllers + Chart.controllers.scatter = Chart.controllers.line; + + Chart.Scatter = function(context, config) { + config.type = 'scatter'; + return new Chart(context, config); + }; + +}; +},{}],15:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.bar = { + hover: { + mode: "label" + }, + + scales: { + xAxes: [{ + type: "category", + + // Specific to Bar Controller + categoryPercentage: 0.8, + barPercentage: 0.9, + + // grid line settings + gridLines: { + offsetGridLines: true + } + }], + yAxes: [{ + type: "linear" + }] + } + }; + + Chart.controllers.bar = Chart.DatasetController.extend({ + + dataElementType: Chart.elements.Rectangle, + + initialize: function(chart, datasetIndex) { + Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex); + + // Use this to indicate that this is a bar dataset. + this.getMeta().bar = true; + }, + + // Get the number of datasets that display bars. We use this to correctly calculate the bar width + getBarCount: function getBarCount() { + var me = this; + var barCount = 0; + helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) { + var meta = me.chart.getDatasetMeta(datasetIndex); + if (meta.bar && me.chart.isDatasetVisible(datasetIndex)) { + ++barCount; + } + }, me); + return barCount; + }, + + update: function update(reset) { + var me = this; + helpers.each(me.getMeta().data, function(rectangle, index) { + me.updateElement(rectangle, index, reset); + }, me); + }, + + updateElement: function updateElement(rectangle, index, reset) { + var me = this; + var meta = me.getMeta(); + var xScale = me.getScaleForId(meta.xAxisID); + var yScale = me.getScaleForId(meta.yAxisID); + var scaleBase = yScale.getBasePixel(); + var rectangleElementOptions = me.chart.options.elements.rectangle; + var custom = rectangle.custom || {}; + var dataset = me.getDataset(); + + helpers.extend(rectangle, { + // Utility + _xScale: xScale, + _yScale: yScale, + _datasetIndex: me.index, + _index: index, + + // Desired view properties + _model: { + x: me.calculateBarX(index, me.index), + y: reset ? scaleBase : me.calculateBarY(index, me.index), + + // Tooltip + label: me.chart.data.labels[index], + datasetLabel: dataset.label, + + // Appearance + base: reset ? scaleBase : me.calculateBarBase(me.index, index), + width: me.calculateBarWidth(index), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), + borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) + } + }); + rectangle.pivot(); + }, + + calculateBarBase: function(datasetIndex, index) { + var me = this; + var meta = me.getMeta(); + var yScale = me.getScaleForId(meta.yAxisID); + var base = 0; + + if (yScale.options.stacked) { + var chart = me.chart; + var datasets = chart.data.datasets; + var value = datasets[datasetIndex].data[index]; + + if (value < 0) { + for (var i = 0; i < datasetIndex; i++) { + var negDS = datasets[i]; + var negDSMeta = chart.getDatasetMeta(i); + if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) { + base += negDS.data[index] < 0 ? negDS.data[index] : 0; + } + } + } else { + for (var j = 0; j < datasetIndex; j++) { + var posDS = datasets[j]; + var posDSMeta = chart.getDatasetMeta(j); + if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(j)) { + base += posDS.data[index] > 0 ? posDS.data[index] : 0; + } + } + } + + return yScale.getPixelForValue(base); + } + + return yScale.getBasePixel(); + }, + + getRuler: function(index) { + var me = this; + var meta = me.getMeta(); + var xScale = me.getScaleForId(meta.xAxisID); + var datasetCount = me.getBarCount(); + + var tickWidth; + + if (xScale.options.type === 'category') { + tickWidth = xScale.getPixelForTick(index + 1) - xScale.getPixelForTick(index); + } else { + // Average width + tickWidth = xScale.width / xScale.ticks.length; + } + var categoryWidth = tickWidth * xScale.options.categoryPercentage; + var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2; + var fullBarWidth = categoryWidth / datasetCount; + + if (xScale.ticks.length !== me.chart.data.labels.length) { + var perc = xScale.ticks.length / me.chart.data.labels.length; + fullBarWidth = fullBarWidth * perc; + } + + var barWidth = fullBarWidth * xScale.options.barPercentage; + var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage); + + return { + datasetCount: datasetCount, + tickWidth: tickWidth, + categoryWidth: categoryWidth, + categorySpacing: categorySpacing, + fullBarWidth: fullBarWidth, + barWidth: barWidth, + barSpacing: barSpacing + }; + }, + + calculateBarWidth: function(index) { + var xScale = this.getScaleForId(this.getMeta().xAxisID); + var ruler = this.getRuler(index); + return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth; + }, + + // Get bar index from the given dataset index accounting for the fact that not all bars are visible + getBarIndex: function(datasetIndex) { + var barIndex = 0; + var meta, j; + + for (j = 0; j < datasetIndex; ++j) { + meta = this.chart.getDatasetMeta(j); + if (meta.bar && this.chart.isDatasetVisible(j)) { + ++barIndex; + } + } + + return barIndex; + }, + + calculateBarX: function(index, datasetIndex) { + var me = this; + var meta = me.getMeta(); + var xScale = me.getScaleForId(meta.xAxisID); + var barIndex = me.getBarIndex(datasetIndex); + + var ruler = me.getRuler(index); + var leftTick = xScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo); + leftTick -= me.chart.isCombo ? (ruler.tickWidth / 2) : 0; + + if (xScale.options.stacked) { + return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing; + } + + return leftTick + + (ruler.barWidth / 2) + + ruler.categorySpacing + + (ruler.barWidth * barIndex) + + (ruler.barSpacing / 2) + + (ruler.barSpacing * barIndex); + }, + + calculateBarY: function(index, datasetIndex) { + var me = this; + var meta = me.getMeta(); + var yScale = me.getScaleForId(meta.yAxisID); + var value = me.getDataset().data[index]; + + if (yScale.options.stacked) { + + var sumPos = 0, + sumNeg = 0; + + for (var i = 0; i < datasetIndex; i++) { + var ds = me.chart.data.datasets[i]; + var dsMeta = me.chart.getDatasetMeta(i); + if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i)) { + if (ds.data[index] < 0) { + sumNeg += ds.data[index] || 0; + } else { + sumPos += ds.data[index] || 0; + } + } + } + + if (value < 0) { + return yScale.getPixelForValue(sumNeg + value); + } else { + return yScale.getPixelForValue(sumPos + value); + } + } + + return yScale.getPixelForValue(value); + }, + + draw: function(ease) { + var me = this; + var easingDecimal = ease || 1; + helpers.each(me.getMeta().data, function(rectangle, index) { + var d = me.getDataset().data[index]; + if (d !== null && d !== undefined && !isNaN(d)) { + rectangle.transition(easingDecimal).draw(); + } + }, me); + }, + + setHoverStyle: function(rectangle) { + var dataset = this.chart.data.datasets[rectangle._datasetIndex]; + var index = rectangle._index; + + var custom = rectangle.custom || {}; + var model = rectangle._model; + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); + }, + + removeHoverStyle: function(rectangle) { + var dataset = this.chart.data.datasets[rectangle._datasetIndex]; + var index = rectangle._index; + var custom = rectangle.custom || {}; + var model = rectangle._model; + var rectangleElementOptions = this.chart.options.elements.rectangle; + + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth); + } + + }); + + + // including horizontalBar in the bar file, instead of a file of its own + // it extends bar (like pie extends doughnut) + Chart.defaults.horizontalBar = { + hover: { + mode: "label" + }, + + scales: { + xAxes: [{ + type: "linear", + position: "bottom" + }], + yAxes: [{ + position: "left", + type: "category", + + // Specific to Horizontal Bar Controller + categoryPercentage: 0.8, + barPercentage: 0.9, + + // grid line settings + gridLines: { + offsetGridLines: true + } + }] + }, + elements: { + rectangle: { + borderSkipped: 'left' + } + }, + tooltips: { + callbacks: { + title: function(tooltipItems, data) { + // Pick first xLabel for now + var title = ''; + + if (tooltipItems.length > 0) { + if (tooltipItems[0].yLabel) { + title = tooltipItems[0].yLabel; + } else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) { + title = data.labels[tooltipItems[0].index]; + } + } + + return title; + }, + label: function(tooltipItem, data) { + var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || ''; + return datasetLabel + ': ' + tooltipItem.xLabel; + } + } + } + }; + + Chart.controllers.horizontalBar = Chart.controllers.bar.extend({ + updateElement: function updateElement(rectangle, index, reset, numBars) { + var me = this; + var meta = me.getMeta(); + var xScale = me.getScaleForId(meta.xAxisID); + var yScale = me.getScaleForId(meta.yAxisID); + var scaleBase = xScale.getBasePixel(); + var custom = rectangle.custom || {}; + var dataset = me.getDataset(); + var rectangleElementOptions = me.chart.options.elements.rectangle; + + helpers.extend(rectangle, { + // Utility + _xScale: xScale, + _yScale: yScale, + _datasetIndex: me.index, + _index: index, + + // Desired view properties + _model: { + x: reset ? scaleBase : me.calculateBarX(index, me.index), + y: me.calculateBarY(index, me.index), + + // Tooltip + label: me.chart.data.labels[index], + datasetLabel: dataset.label, + + // Appearance + base: reset ? scaleBase : me.calculateBarBase(me.index, index), + height: me.calculateBarHeight(index), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), + borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) + }, + + draw: function () { + var ctx = this._chart.ctx; + var vm = this._view; + + var halfHeight = vm.height / 2, + topY = vm.y - halfHeight, + bottomY = vm.y + halfHeight, + right = vm.base - (vm.base - vm.x), + halfStroke = vm.borderWidth / 2; + + // Canvas doesn't allow us to stroke inside the width so we can + // adjust the sizes to fit if we're setting a stroke on the line + if (vm.borderWidth) { + topY += halfStroke; + bottomY -= halfStroke; + right += halfStroke; + } + + ctx.beginPath(); + + ctx.fillStyle = vm.backgroundColor; + ctx.strokeStyle = vm.borderColor; + ctx.lineWidth = vm.borderWidth; + + // Corner points, from bottom-left to bottom-right clockwise + // | 1 2 | + // | 0 3 | + var corners = [ + [vm.base, bottomY], + [vm.base, topY], + [right, topY], + [right, bottomY] + ]; + + // Find first (starting) corner with fallback to 'bottom' + var borders = ['bottom', 'left', 'top', 'right']; + var startCorner = borders.indexOf(vm.borderSkipped, 0); + if (startCorner === -1) + startCorner = 0; + + function cornerAt(index) { + return corners[(startCorner + index) % 4]; + } + + // Draw rectangle from 'startCorner' + ctx.moveTo.apply(ctx, cornerAt(0)); + for (var i = 1; i < 4; i++) + ctx.lineTo.apply(ctx, cornerAt(i)); + + ctx.fill(); + if (vm.borderWidth) { + ctx.stroke(); + } + }, + + inRange: function (mouseX, mouseY) { + var vm = this._view; + var inRange = false; + + if (vm) { + if (vm.x < vm.base) { + inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base); + } else { + inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x); + } + } + + return inRange; + } + }); + + rectangle.pivot(); + }, + + calculateBarBase: function (datasetIndex, index) { + var me = this; + var meta = me.getMeta(); + var xScale = me.getScaleForId(meta.xAxisID); + var base = 0; + + if (xScale.options.stacked) { + + var value = me.chart.data.datasets[datasetIndex].data[index]; + + if (value < 0) { + for (var i = 0; i < datasetIndex; i++) { + var negDS = me.chart.data.datasets[i]; + var negDSMeta = me.chart.getDatasetMeta(i); + if (negDSMeta.bar && negDSMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) { + base += negDS.data[index] < 0 ? negDS.data[index] : 0; + } + } + } else { + for (var j = 0; j < datasetIndex; j++) { + var posDS = me.chart.data.datasets[j]; + var posDSMeta = me.chart.getDatasetMeta(j); + if (posDSMeta.bar && posDSMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(j)) { + base += posDS.data[index] > 0 ? posDS.data[index] : 0; + } + } + } + + return xScale.getPixelForValue(base); + } + + return xScale.getBasePixel(); + }, + + getRuler: function (index) { + var me = this; + var meta = me.getMeta(); + var yScale = me.getScaleForId(meta.yAxisID); + var datasetCount = me.getBarCount(); + + var tickHeight; + if (yScale.options.type === 'category') { + tickHeight = yScale.getPixelForTick(index + 1) - yScale.getPixelForTick(index); + } else { + // Average width + tickHeight = yScale.width / yScale.ticks.length; + } + var categoryHeight = tickHeight * yScale.options.categoryPercentage; + var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2; + var fullBarHeight = categoryHeight / datasetCount; + + if (yScale.ticks.length !== me.chart.data.labels.length) { + var perc = yScale.ticks.length / me.chart.data.labels.length; + fullBarHeight = fullBarHeight * perc; + } + + var barHeight = fullBarHeight * yScale.options.barPercentage; + var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage); + + return { + datasetCount: datasetCount, + tickHeight: tickHeight, + categoryHeight: categoryHeight, + categorySpacing: categorySpacing, + fullBarHeight: fullBarHeight, + barHeight: barHeight, + barSpacing: barSpacing, + }; + }, + + calculateBarHeight: function (index) { + var me = this; + var yScale = me.getScaleForId(me.getMeta().yAxisID); + var ruler = me.getRuler(index); + return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight; + }, + + calculateBarX: function (index, datasetIndex) { + var me = this; + var meta = me.getMeta(); + var xScale = me.getScaleForId(meta.xAxisID); + var value = me.getDataset().data[index]; + + if (xScale.options.stacked) { + + var sumPos = 0, + sumNeg = 0; + + for (var i = 0; i < datasetIndex; i++) { + var ds = me.chart.data.datasets[i]; + var dsMeta = me.chart.getDatasetMeta(i); + if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) { + if (ds.data[index] < 0) { + sumNeg += ds.data[index] || 0; + } else { + sumPos += ds.data[index] || 0; + } + } + } + + if (value < 0) { + return xScale.getPixelForValue(sumNeg + value); + } else { + return xScale.getPixelForValue(sumPos + value); + } + } + + return xScale.getPixelForValue(value); + }, + + calculateBarY: function (index, datasetIndex) { + var me = this; + var meta = me.getMeta(); + var yScale = me.getScaleForId(meta.yAxisID); + var barIndex = me.getBarIndex(datasetIndex); + + var ruler = me.getRuler(index); + var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo); + topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0; + + if (yScale.options.stacked) { + return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing; + } + + return topTick + + (ruler.barHeight / 2) + + ruler.categorySpacing + + (ruler.barHeight * barIndex) + + (ruler.barSpacing / 2) + + (ruler.barSpacing * barIndex); + } + }); +}; + +},{}],16:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.bubble = { + hover: { + mode: "single" + }, + + scales: { + xAxes: [{ + type: "linear", // bubble should probably use a linear scale by default + position: "bottom", + id: "x-axis-0" // need an ID so datasets can reference the scale + }], + yAxes: [{ + type: "linear", + position: "left", + id: "y-axis-0" + }] + }, + + tooltips: { + callbacks: { + title: function(tooltipItems, data) { + // Title doesn't make sense for scatter since we format the data as a point + return ''; + }, + label: function(tooltipItem, data) { + var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || ''; + var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; + return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')'; + } + } + } + }; + + Chart.controllers.bubble = Chart.DatasetController.extend({ + + dataElementType: Chart.elements.Point, + + update: function update(reset) { + var me = this; + var meta = me.getMeta(); + var points = meta.data; + + // Update Points + helpers.each(points, function(point, index) { + me.updateElement(point, index, reset); + }); + }, + + updateElement: function(point, index, reset) { + var me = this; + var meta = me.getMeta(); + var xScale = me.getScaleForId(meta.xAxisID); + var yScale = me.getScaleForId(meta.yAxisID); + + var custom = point.custom || {}; + var dataset = me.getDataset(); + var data = dataset.data[index]; + var pointElementOptions = me.chart.options.elements.point; + var dsIndex = me.index; + + helpers.extend(point, { + // Utility + _xScale: xScale, + _yScale: yScale, + _datasetIndex: dsIndex, + _index: index, + + // Desired view properties + _model: { + x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(data, index, dsIndex, me.chart.isCombo), + y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex), + // Appearance + radius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data), + + // Tooltip + hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius) + } + }); + + // Trick to reset the styles of the point + Chart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions); + + var model = point._model; + model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y)); + + point.pivot(); + }, + + getRadius: function(value) { + return value.r || this.chart.options.elements.point.radius; + }, + + setHoverStyle: function(point) { + var me = this; + Chart.DatasetController.prototype.setHoverStyle.call(me, point); + + // Radius + var dataset = me.chart.data.datasets[point._datasetIndex]; + var index = point._index; + var custom = point.custom || {}; + var model = point._model; + model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]); + }, + + removeHoverStyle: function(point) { + var me = this; + Chart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point); + + var dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index]; + var custom = point.custom || {}; + var model = point._model; + + model.radius = custom.radius ? custom.radius : me.getRadius(dataVal); + } + }); +}; + +},{}],17:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers, + defaults = Chart.defaults; + + defaults.doughnut = { + animation: { + //Boolean - Whether we animate the rotation of the Doughnut + animateRotate: true, + //Boolean - Whether we animate scaling the Doughnut from the centre + animateScale: false + }, + aspectRatio: 1, + hover: { + mode: 'single' + }, + legendCallback: function(chart) { + var text = []; + text.push('
    '); + + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + + if (datasets.length) { + for (var i = 0; i < datasets[0].data.length; ++i) { + text.push('
  • '); + if (labels[i]) { + text.push(labels[i]); + } + text.push('
  • '); + } + } + + text.push('
'); + return text.join(""); + }, + legend: { + labels: { + generateLabels: function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0); + var ds = data.datasets[0]; + var arc = meta.data[i]; + var custom = arc.custom || {}; + var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; + var arcOpts = chart.options.elements.arc; + var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); + var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); + var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); + + return { + text: label, + fillStyle: fill, + strokeStyle: stroke, + lineWidth: bw, + hidden: isNaN(ds.data[i]) || meta.data[i].hidden, + + // Extra data used for toggling the correct item + index: i + }; + }); + } else { + return []; + } + } + }, + + onClick: function(e, legendItem) { + var index = legendItem.index; + var chart = this.chart; + var i, ilen, meta; + + for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { + meta = chart.getDatasetMeta(i); + meta.data[index].hidden = !meta.data[index].hidden; + } + + chart.update(); + } + }, + + //The percentage of the chart that we cut out of the middle. + cutoutPercentage: 50, + + //The rotation of the chart, where the first data arc begins. + rotation: Math.PI * -0.5, + + //The total circumference of the chart. + circumference: Math.PI * 2.0, + + // Need to override these to give a nice default + tooltips: { + callbacks: { + title: function() { + return ''; + }, + label: function(tooltipItem, data) { + return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; + } + } + } + }; + + defaults.pie = helpers.clone(defaults.doughnut); + helpers.extend(defaults.pie, { + cutoutPercentage: 0 + }); + + + Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({ + + dataElementType: Chart.elements.Arc, + + linkScales: helpers.noop, + + // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly + getRingIndex: function getRingIndex(datasetIndex) { + var ringIndex = 0; + + for (var j = 0; j < datasetIndex; ++j) { + if (this.chart.isDatasetVisible(j)) { + ++ringIndex; + } + } + + return ringIndex; + }, + + update: function update(reset) { + var me = this; + var chart = me.chart, + chartArea = chart.chartArea, + opts = chart.options, + arcOpts = opts.elements.arc, + availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth, + availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth, + minSize = Math.min(availableWidth, availableHeight), + offset = { + x: 0, + y: 0 + }, + meta = me.getMeta(), + cutoutPercentage = opts.cutoutPercentage, + circumference = opts.circumference; + + // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc + if (circumference < Math.PI * 2.0) { + var startAngle = opts.rotation % (Math.PI * 2.0); + startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0); + var endAngle = startAngle + circumference; + var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)}; + var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)}; + var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle); + var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle); + var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle); + var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle); + var cutout = cutoutPercentage / 100.0; + var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))}; + var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))}; + var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5}; + minSize = Math.min(availableWidth / size.width, availableHeight / size.height); + offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5}; + } + + chart.outerRadius = Math.max(minSize / 2, 0); + chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 1, 0); + chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); + chart.offsetX = offset.x * chart.outerRadius; + chart.offsetY = offset.y * chart.outerRadius; + + meta.total = me.calculateTotal(); + + me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index)); + me.innerRadius = me.outerRadius - chart.radiusLength; + + helpers.each(meta.data, function(arc, index) { + me.updateElement(arc, index, reset); + }); + }, + + updateElement: function(arc, index, reset) { + var me = this; + var chart = me.chart, + chartArea = chart.chartArea, + opts = chart.options, + animationOpts = opts.animation, + arcOpts = opts.elements.arc, + centerX = (chartArea.left + chartArea.right) / 2, + centerY = (chartArea.top + chartArea.bottom) / 2, + startAngle = opts.rotation, // non reset case handled later + endAngle = opts.rotation, // non reset case handled later + dataset = me.getDataset(), + circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)), + innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius, + outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius, + custom = arc.custom || {}, + valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; + + helpers.extend(arc, { + // Utility + _datasetIndex: me.index, + _index: index, + + // Desired view properties + _model: { + x: centerX + chart.offsetX, + y: centerY + chart.offsetY, + startAngle: startAngle, + endAngle: endAngle, + circumference: circumference, + outerRadius: outerRadius, + innerRadius: innerRadius, + label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index]) + } + }); + + var model = arc._model; + // Resets the visual styles + this.removeHoverStyle(arc); + + // Set correct angles if not resetting + if (!reset || !animationOpts.animateRotate) { + if (index === 0) { + model.startAngle = opts.rotation; + } else { + model.startAngle = me.getMeta().data[index - 1]._model.endAngle; + } + + model.endAngle = model.startAngle + model.circumference; + } + + arc.pivot(); + }, + + removeHoverStyle: function(arc) { + Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc); + }, + + calculateTotal: function() { + var dataset = this.getDataset(); + var meta = this.getMeta(); + var total = 0; + var value; + + helpers.each(meta.data, function(element, index) { + value = dataset.data[index]; + if (!isNaN(value) && !element.hidden) { + total += Math.abs(value); + } + }); + + return total; + }, + + calculateCircumference: function(value) { + var total = this.getMeta().total; + if (total > 0 && !isNaN(value)) { + return (Math.PI * 2.0) * (value / total); + } else { + return 0; + } + } + }); +}; + +},{}],18:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.line = { + showLines: true, + + hover: { + mode: "label" + }, + + scales: { + xAxes: [{ + type: "category", + id: 'x-axis-0' + }], + yAxes: [{ + type: "linear", + id: 'y-axis-0' + }] + } + }; + + function lineEnabled(dataset, options) { + return helpers.getValueOrDefault(dataset.showLine, options.showLines); + } + + Chart.controllers.line = Chart.DatasetController.extend({ + + datasetElementType: Chart.elements.Line, + + dataElementType: Chart.elements.Point, + + addElementAndReset: function(index) { + var me = this; + var options = me.chart.options; + var meta = me.getMeta(); + + Chart.DatasetController.prototype.addElementAndReset.call(me, index); + + // Make sure bezier control points are updated + if (lineEnabled(me.getDataset(), options) && meta.dataset._model.tension !== 0) { + me.updateBezierControlPoints(); + } + }, + + update: function update(reset) { + var me = this; + var meta = me.getMeta(); + var line = meta.dataset; + var points = meta.data || []; + var options = me.chart.options; + var lineElementOptions = options.elements.line; + var scale = me.getScaleForId(meta.yAxisID); + var i, ilen, custom; + var dataset = me.getDataset(); + var showLine = lineEnabled(dataset, options); + + // Update Line + if (showLine) { + custom = line.custom || {}; + + // Compatibility: If the properties are defined with only the old name, use those values + if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { + dataset.lineTension = dataset.tension; + } + + // Utility + line._scale = scale; + line._datasetIndex = me.index; + // Data + line._children = points; + // Model + line._model = { + // Appearance + // The default behavior of lines is to break at null values, according + // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158 + // This option gives linse the ability to span gaps + spanGaps: dataset.spanGaps ? dataset.spanGaps : false, + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), + borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), + borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), + borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), + borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), + fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), + // Scale + scaleTop: scale.top, + scaleBottom: scale.bottom, + scaleZero: scale.getBasePixel() + }; + + line.pivot(); + } + + // Update Points + for (i=0, ilen=points.length; i'); + + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + + if (datasets.length) { + for (var i = 0; i < datasets[0].data.length; ++i) { + text.push('
  • '); + if (labels[i]) { + text.push(labels[i]); + } + text.push('
  • '); + } + } + + text.push(''); + return text.join(""); + }, + legend: { + labels: { + generateLabels: function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0); + var ds = data.datasets[0]; + var arc = meta.data[i]; + var custom = arc.custom || {}; + var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; + var arcOpts = chart.options.elements.arc; + var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); + var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); + var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); + + return { + text: label, + fillStyle: fill, + strokeStyle: stroke, + lineWidth: bw, + hidden: isNaN(ds.data[i]) || meta.data[i].hidden, + + // Extra data used for toggling the correct item + index: i + }; + }); + } else { + return []; + } + } + }, + + onClick: function(e, legendItem) { + var index = legendItem.index; + var chart = this.chart; + var i, ilen, meta; + + for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { + meta = chart.getDatasetMeta(i); + meta.data[index].hidden = !meta.data[index].hidden; + } + + chart.update(); + } + }, + + // Need to override these to give a nice default + tooltips: { + callbacks: { + title: function() { + return ''; + }, + label: function(tooltipItem, data) { + return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel; + } + } + } + }; + + Chart.controllers.polarArea = Chart.DatasetController.extend({ + + dataElementType: Chart.elements.Arc, + + linkScales: helpers.noop, + + update: function update(reset) { + var me = this; + var chart = me.chart; + var chartArea = chart.chartArea; + var meta = me.getMeta(); + var opts = chart.options; + var arcOpts = opts.elements.arc; + var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); + chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0); + chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0); + chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); + + me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index); + me.innerRadius = me.outerRadius - chart.radiusLength; + + meta.count = me.countVisibleElements(); + + helpers.each(meta.data, function(arc, index) { + me.updateElement(arc, index, reset); + }); + }, + + updateElement: function(arc, index, reset) { + var me = this; + var chart = me.chart; + var chartArea = chart.chartArea; + var dataset = me.getDataset(); + var opts = chart.options; + var animationOpts = opts.animation; + var arcOpts = opts.elements.arc; + var custom = arc.custom || {}; + var scale = chart.scale; + var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; + var labels = chart.data.labels; + + var circumference = me.calculateCircumference(dataset.data[index]); + var centerX = (chartArea.left + chartArea.right) / 2; + var centerY = (chartArea.top + chartArea.bottom) / 2; + + // If there is NaN data before us, we need to calculate the starting angle correctly. + // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data + var visibleCount = 0; + var meta = me.getMeta(); + for (var i = 0; i < index; ++i) { + if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) { + ++visibleCount; + } + } + + var negHalfPI = -0.5 * Math.PI; + var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); + var startAngle = (negHalfPI) + (circumference * visibleCount); + var endAngle = startAngle + (arc.hidden ? 0 : circumference); + + var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); + + helpers.extend(arc, { + // Utility + _datasetIndex: me.index, + _index: index, + _scale: scale, + + // Desired view properties + _model: { + x: centerX, + y: centerY, + innerRadius: 0, + outerRadius: reset ? resetRadius : distance, + startAngle: reset && animationOpts.animateRotate ? negHalfPI : startAngle, + endAngle: reset && animationOpts.animateRotate ? negHalfPI : endAngle, + label: getValueAtIndexOrDefault(labels, index, labels[index]) + } + }); + + // Apply border and fill style + me.removeHoverStyle(arc); + + arc.pivot(); + }, + + removeHoverStyle: function(arc) { + Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc); + }, + + countVisibleElements: function() { + var dataset = this.getDataset(); + var meta = this.getMeta(); + var count = 0; + + helpers.each(meta.data, function(element, index) { + if (!isNaN(dataset.data[index]) && !element.hidden) { + count++; + } + }); + + return count; + }, + + calculateCircumference: function(value) { + var count = this.getMeta().count; + if (count > 0 && !isNaN(value)) { + return (2 * Math.PI) / count; + } else { + return 0; + } + } + }); +}; + +},{}],20:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.radar = { + scale: { + type: "radialLinear" + }, + elements: { + line: { + tension: 0 // no bezier in radar + } + } + }; + + Chart.controllers.radar = Chart.DatasetController.extend({ + + datasetElementType: Chart.elements.Line, + + dataElementType: Chart.elements.Point, + + linkScales: helpers.noop, + + addElementAndReset: function(index) { + Chart.DatasetController.prototype.addElementAndReset.call(this, index); + + // Make sure bezier control points are updated + this.updateBezierControlPoints(); + }, + + update: function update(reset) { + var me = this; + var meta = me.getMeta(); + var line = meta.dataset; + var points = meta.data; + var custom = line.custom || {}; + var dataset = me.getDataset(); + var lineElementOptions = me.chart.options.elements.line; + var scale = me.chart.scale; + + // Compatibility: If the properties are defined with only the old name, use those values + if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { + dataset.lineTension = dataset.tension; + } + + helpers.extend(meta.dataset, { + // Utility + _datasetIndex: me.index, + // Data + _children: points, + _loop: true, + // Model + _model: { + // Appearance + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), + fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), + borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), + borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), + borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), + borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), + + // Scale + scaleTop: scale.top, + scaleBottom: scale.bottom, + scaleZero: scale.getBasePosition() + } + }); + + meta.dataset.pivot(); + + // Update Points + helpers.each(points, function(point, index) { + me.updateElement(point, index, reset); + }, me); + + + // Update bezier control points + me.updateBezierControlPoints(); + }, + updateElement: function(point, index, reset) { + var me = this; + var custom = point.custom || {}; + var dataset = me.getDataset(); + var scale = me.chart.scale; + var pointElementOptions = me.chart.options.elements.point; + var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); + + helpers.extend(point, { + // Utility + _datasetIndex: me.index, + _index: index, + _scale: scale, + + // Desired view properties + _model: { + x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales + y: reset ? scale.yCenter : pointPosition.y, + + // Appearance + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, me.chart.options.elements.line.tension), + radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor), + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth), + pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle), + + // Tooltip + hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius) + } + }); + + point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); + }, + updateBezierControlPoints: function() { + var chartArea = this.chart.chartArea; + var meta = this.getMeta(); + + helpers.each(meta.data, function(point, index) { + var model = point._model; + var controlPoints = helpers.splineCurve( + helpers.previousItem(meta.data, index, true)._model, + model, + helpers.nextItem(meta.data, index, true)._model, + model.tension + ); + + // Prevent the bezier going outside of the bounds of the graph + model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left); + model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top); + + model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left); + model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top); + + // Now pivot the point for animation + point.pivot(); + }); + }, + + draw: function(ease) { + var meta = this.getMeta(); + var easingDecimal = ease || 1; + + // Transition Point Locations + helpers.each(meta.data, function(point, index) { + point.transition(easingDecimal); + }); + + // Transition and Draw the line + meta.dataset.transition(easingDecimal).draw(); + + // Draw the points + helpers.each(meta.data, function(point) { + point.draw(); + }); + }, + + setHoverStyle: function(point) { + // Point + var dataset = this.chart.data.datasets[point._datasetIndex]; + var custom = point.custom || {}; + var index = point._index; + var model = point._model; + + model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth); + }, + + removeHoverStyle: function(point) { + var dataset = this.chart.data.datasets[point._datasetIndex]; + var custom = point.custom || {}; + var index = point._index; + var model = point._model; + var pointElementOptions = this.chart.options.elements.point; + + model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.radius, index, pointElementOptions.radius); + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth); + } + }); +}; + +},{}],21:[function(require,module,exports){ +/*global window: false */ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.global.animation = { + duration: 1000, + easing: "easeOutQuart", + onProgress: helpers.noop, + onComplete: helpers.noop + }; + + Chart.Animation = Chart.Element.extend({ + currentStep: null, // the current animation step + numSteps: 60, // default number of steps + easing: "", // the easing to use for this animation + render: null, // render function used by the animation service + + onAnimationProgress: null, // user specified callback to fire on each step of the animation + onAnimationComplete: null // user specified callback to fire when the animation finishes + }); + + Chart.animationService = { + frameDuration: 17, + animations: [], + dropFrames: 0, + request: null, + addAnimation: function(chartInstance, animationObject, duration, lazy) { + var me = this; + + if (!lazy) { + chartInstance.animating = true; + } + + for (var index = 0; index < me.animations.length; ++index) { + if (me.animations[index].chartInstance === chartInstance) { + // replacing an in progress animation + me.animations[index].animationObject = animationObject; + return; + } + } + + me.animations.push({ + chartInstance: chartInstance, + animationObject: animationObject + }); + + // If there are no animations queued, manually kickstart a digest, for lack of a better word + if (me.animations.length === 1) { + me.requestAnimationFrame(); + } + }, + // Cancel the animation for a given chart instance + cancelAnimation: function(chartInstance) { + var index = helpers.findIndex(this.animations, function(animationWrapper) { + return animationWrapper.chartInstance === chartInstance; + }); + + if (index !== -1) { + this.animations.splice(index, 1); + chartInstance.animating = false; + } + }, + requestAnimationFrame: function() { + var me = this; + if (me.request === null) { + // Skip animation frame requests until the active one is executed. + // This can happen when processing mouse events, e.g. 'mousemove' + // and 'mouseout' events will trigger multiple renders. + me.request = helpers.requestAnimFrame.call(window, function() { + me.request = null; + me.startDigest(); + }); + } + }, + startDigest: function() { + var me = this; + + var startTime = Date.now(); + var framesToDrop = 0; + + if (me.dropFrames > 1) { + framesToDrop = Math.floor(me.dropFrames); + me.dropFrames = me.dropFrames % 1; + } + + var i = 0; + while (i < me.animations.length) { + if (me.animations[i].animationObject.currentStep === null) { + me.animations[i].animationObject.currentStep = 0; + } + + me.animations[i].animationObject.currentStep += 1 + framesToDrop; + + if (me.animations[i].animationObject.currentStep > me.animations[i].animationObject.numSteps) { + me.animations[i].animationObject.currentStep = me.animations[i].animationObject.numSteps; + } + + me.animations[i].animationObject.render(me.animations[i].chartInstance, me.animations[i].animationObject); + if (me.animations[i].animationObject.onAnimationProgress && me.animations[i].animationObject.onAnimationProgress.call) { + me.animations[i].animationObject.onAnimationProgress.call(me.animations[i].chartInstance, me.animations[i]); + } + + if (me.animations[i].animationObject.currentStep === me.animations[i].animationObject.numSteps) { + if (me.animations[i].animationObject.onAnimationComplete && me.animations[i].animationObject.onAnimationComplete.call) { + me.animations[i].animationObject.onAnimationComplete.call(me.animations[i].chartInstance, me.animations[i]); + } + + // executed the last frame. Remove the animation. + me.animations[i].chartInstance.animating = false; + + me.animations.splice(i, 1); + } else { + ++i; + } + } + + var endTime = Date.now(); + var dropFrames = (endTime - startTime) / me.frameDuration; + + me.dropFrames += dropFrames; + + // Do we have more stuff to animate? + if (me.animations.length > 0) { + me.requestAnimationFrame(); + } + } + }; +}; +},{}],22:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + //Create a dictionary of chart types, to allow for extension of existing types + Chart.types = {}; + + //Store a reference to each instance - allowing us to globally resize chart instances on window resize. + //Destroy method on the chart will remove the instance of the chart from this reference. + Chart.instances = {}; + + // Controllers available for dataset visualization eg. bar, line, slice, etc. + Chart.controllers = {}; + + /** + * @class Chart.Controller + * The main controller of a chart. + */ + Chart.Controller = function(instance) { + + this.chart = instance; + this.config = instance.config; + this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {}); + this.id = helpers.uid(); + + Object.defineProperty(this, 'data', { + get: function() { + return this.config.data; + } + }); + + //Add the chart instance to the global namespace + Chart.instances[this.id] = this; + + if (this.options.responsive) { + // Silent resize before chart draws + this.resize(true); + } + + this.initialize(); + + return this; + }; + + helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ { + + initialize: function initialize() { + var me = this; + // Before init plugin notification + Chart.plugins.notify('beforeInit', [me]); + + me.bindEvents(); + + // Make sure controllers are built first so that each dataset is bound to an axis before the scales + // are built + me.ensureScalesHaveIDs(); + me.buildOrUpdateControllers(); + me.buildScales(); + me.updateLayout(); + me.resetElements(); + me.initToolTip(); + me.update(); + + // After init plugin notification + Chart.plugins.notify('afterInit', [me]); + + return me; + }, + + clear: function clear() { + helpers.clear(this.chart); + return this; + }, + + stop: function stop() { + // Stops any current animation loop occuring + Chart.animationService.cancelAnimation(this); + return this; + }, + + resize: function resize(silent) { + var me = this; + var chart = me.chart; + var canvas = chart.canvas; + var newWidth = helpers.getMaximumWidth(canvas); + var aspectRatio = chart.aspectRatio; + var newHeight = (me.options.maintainAspectRatio && isNaN(aspectRatio) === false && isFinite(aspectRatio) && aspectRatio !== 0) ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas); + + var sizeChanged = chart.width !== newWidth || chart.height !== newHeight; + + if (!sizeChanged) { + return me; + } + + canvas.width = chart.width = newWidth; + canvas.height = chart.height = newHeight; + + helpers.retinaScale(chart); + + // Notify any plugins about the resize + var newSize = { width: newWidth, height: newHeight }; + Chart.plugins.notify('resize', [me, newSize]); + + // Notify of resize + if (me.options.onResize) { + me.options.onResize(me, newSize); + } + + if (!silent) { + me.stop(); + me.update(me.options.responsiveAnimationDuration); + } + + return me; + }, + + ensureScalesHaveIDs: function ensureScalesHaveIDs() { + var options = this.options; + var scalesOptions = options.scales || {}; + var scaleOptions = options.scale; + + helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) { + xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index); + }); + + helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) { + yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index); + }); + + if (scaleOptions) { + scaleOptions.id = scaleOptions.id || 'scale'; + } + }, + + /** + * Builds a map of scale ID to scale object for future lookup. + */ + buildScales: function buildScales() { + var me = this; + var options = me.options; + var scales = me.scales = {}; + var items = []; + + if (options.scales) { + items = items.concat( + (options.scales.xAxes || []).map(function(xAxisOptions) { + return { options: xAxisOptions, dtype: 'category' }; }), + (options.scales.yAxes || []).map(function(yAxisOptions) { + return { options: yAxisOptions, dtype: 'linear' }; })); + } + + if (options.scale) { + items.push({ options: options.scale, dtype: 'radialLinear', isDefault: true }); + } + + helpers.each(items, function(item, index) { + var scaleOptions = item.options; + var scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype); + var scaleClass = Chart.scaleService.getScaleConstructor(scaleType); + if (!scaleClass) { + return; + } + + var scale = new scaleClass({ + id: scaleOptions.id, + options: scaleOptions, + ctx: me.chart.ctx, + chart: me + }); + + scales[scale.id] = scale; + + // TODO(SB): I think we should be able to remove this custom case (options.scale) + // and consider it as a regular scale part of the "scales"" map only! This would + // make the logic easier and remove some useless? custom code. + if (item.isDefault) { + me.scale = scale; + } + }); + + Chart.scaleService.addScalesToLayout(this); + }, + + updateLayout: function() { + Chart.layoutService.update(this, this.chart.width, this.chart.height); + }, + + buildOrUpdateControllers: function buildOrUpdateControllers() { + var me = this; + var types = []; + var newControllers = []; + + helpers.each(me.data.datasets, function(dataset, datasetIndex) { + var meta = me.getDatasetMeta(datasetIndex); + if (!meta.type) { + meta.type = dataset.type || me.config.type; + } + + types.push(meta.type); + + if (meta.controller) { + meta.controller.updateIndex(datasetIndex); + } else { + meta.controller = new Chart.controllers[meta.type](me, datasetIndex); + newControllers.push(meta.controller); + } + }, me); + + if (types.length > 1) { + for (var i = 1; i < types.length; i++) { + if (types[i] !== types[i - 1]) { + me.isCombo = true; + break; + } + } + } + + return newControllers; + }, + + resetElements: function resetElements() { + var me = this; + helpers.each(me.data.datasets, function(dataset, datasetIndex) { + me.getDatasetMeta(datasetIndex).controller.reset(); + }, me); + }, + + update: function update(animationDuration, lazy) { + var me = this; + Chart.plugins.notify('beforeUpdate', [me]); + + // In case the entire data object changed + me.tooltip._data = me.data; + + // Make sure dataset controllers are updated and new controllers are reset + var newControllers = me.buildOrUpdateControllers(); + + // Make sure all dataset controllers have correct meta data counts + helpers.each(me.data.datasets, function(dataset, datasetIndex) { + me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements(); + }, me); + + Chart.layoutService.update(me, me.chart.width, me.chart.height); + + // Apply changes to the dataets that require the scales to have been calculated i.e BorderColor chages + Chart.plugins.notify('afterScaleUpdate', [me]); + + // Can only reset the new controllers after the scales have been updated + helpers.each(newControllers, function(controller) { + controller.reset(); + }); + + me.updateDatasets(); + + // Do this before render so that any plugins that need final scale updates can use it + Chart.plugins.notify('afterUpdate', [me]); + + me.render(animationDuration, lazy); + }, + + /** + * @method beforeDatasetsUpdate + * @description Called before all datasets are updated. If a plugin returns false, + * the datasets update will be cancelled until another chart update is triggered. + * @param {Object} instance the chart instance being updated. + * @returns {Boolean} false to cancel the datasets update. + * @memberof Chart.PluginBase + * @since version 2.1.5 + * @instance + */ + + /** + * @method afterDatasetsUpdate + * @description Called after all datasets have been updated. Note that this + * extension will not be called if the datasets update has been cancelled. + * @param {Object} instance the chart instance being updated. + * @memberof Chart.PluginBase + * @since version 2.1.5 + * @instance + */ + + /** + * Updates all datasets unless a plugin returns false to the beforeDatasetsUpdate + * extension, in which case no datasets will be updated and the afterDatasetsUpdate + * notification will be skipped. + * @protected + * @instance + */ + updateDatasets: function() { + var me = this; + var i, ilen; + + if (Chart.plugins.notify('beforeDatasetsUpdate', [ me ])) { + for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) { + me.getDatasetMeta(i).controller.update(); + } + + Chart.plugins.notify('afterDatasetsUpdate', [ me ]); + } + }, + + render: function render(duration, lazy) { + var me = this; + Chart.plugins.notify('beforeRender', [me]); + + var animationOptions = me.options.animation; + if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) { + var animation = new Chart.Animation(); + animation.numSteps = (duration || animationOptions.duration) / 16.66; //60 fps + animation.easing = animationOptions.easing; + + // render function + animation.render = function(chartInstance, animationObject) { + var easingFunction = helpers.easingEffects[animationObject.easing]; + var stepDecimal = animationObject.currentStep / animationObject.numSteps; + var easeDecimal = easingFunction(stepDecimal); + + chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep); + }; + + // user events + animation.onAnimationProgress = animationOptions.onProgress; + animation.onAnimationComplete = animationOptions.onComplete; + + Chart.animationService.addAnimation(me, animation, duration, lazy); + } else { + me.draw(); + if (animationOptions && animationOptions.onComplete && animationOptions.onComplete.call) { + animationOptions.onComplete.call(me); + } + } + return me; + }, + + draw: function(ease) { + var me = this; + var easingDecimal = ease || 1; + me.clear(); + + Chart.plugins.notify('beforeDraw', [me, easingDecimal]); + + // Draw all the scales + helpers.each(me.boxes, function(box) { + box.draw(me.chartArea); + }, me); + if (me.scale) { + me.scale.draw(); + } + + Chart.plugins.notify('beforeDatasetsDraw', [me, easingDecimal]); + + // Draw each dataset via its respective controller (reversed to support proper line stacking) + helpers.each(me.data.datasets, function(dataset, datasetIndex) { + if (me.isDatasetVisible(datasetIndex)) { + me.getDatasetMeta(datasetIndex).controller.draw(ease); + } + }, me, true); + + Chart.plugins.notify('afterDatasetsDraw', [me, easingDecimal]); + + // Finally draw the tooltip + me.tooltip.transition(easingDecimal).draw(); + + Chart.plugins.notify('afterDraw', [me, easingDecimal]); + }, + + // Get the single element that was clicked on + // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw + getElementAtEvent: function(e) { + var me = this; + var eventPosition = helpers.getRelativePosition(e, me.chart); + var elementsArray = []; + + helpers.each(me.data.datasets, function(dataset, datasetIndex) { + if (me.isDatasetVisible(datasetIndex)) { + var meta = me.getDatasetMeta(datasetIndex); + helpers.each(meta.data, function(element, index) { + if (element.inRange(eventPosition.x, eventPosition.y)) { + elementsArray.push(element); + return elementsArray; + } + }); + } + }); + + return elementsArray; + }, + + getElementsAtEvent: function(e) { + var me = this; + var eventPosition = helpers.getRelativePosition(e, me.chart); + var elementsArray = []; + + var found = (function() { + if (me.data.datasets) { + for (var i = 0; i < me.data.datasets.length; i++) { + var meta = me.getDatasetMeta(i); + if (me.isDatasetVisible(i)) { + for (var j = 0; j < meta.data.length; j++) { + if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) { + return meta.data[j]; + } + } + } + } + } + }).call(me); + + if (!found) { + return elementsArray; + } + + helpers.each(me.data.datasets, function(dataset, datasetIndex) { + if (me.isDatasetVisible(datasetIndex)) { + var meta = me.getDatasetMeta(datasetIndex); + elementsArray.push(meta.data[found._index]); + } + }, me); + + return elementsArray; + }, + + getElementsAtEventForMode: function(e, mode) { + var me = this; + switch (mode) { + case 'single': + return me.getElementAtEvent(e); + case 'label': + return me.getElementsAtEvent(e); + case 'dataset': + return me.getDatasetAtEvent(e); + default: + return e; + } + }, + + getDatasetAtEvent: function(e) { + var elementsArray = this.getElementAtEvent(e); + + if (elementsArray.length > 0) { + elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data; + } + + return elementsArray; + }, + + getDatasetMeta: function(datasetIndex) { + var me = this; + var dataset = me.data.datasets[datasetIndex]; + if (!dataset._meta) { + dataset._meta = {}; + } + + var meta = dataset._meta[me.id]; + if (!meta) { + meta = dataset._meta[me.id] = { + type: null, + data: [], + dataset: null, + controller: null, + hidden: null, // See isDatasetVisible() comment + xAxisID: null, + yAxisID: null + }; + } + + return meta; + }, + + getVisibleDatasetCount: function() { + var count = 0; + for (var i = 0, ilen = this.data.datasets.length; i
    "; -$GRAPH.=""; -$GRAPH.="
    "._QXZ("XFERS").""._QXZ("SALE")." %"._QXZ("SALE").""._QXZ("DROP").""._QXZ("OTHER")."

     


    "; -$graph_header=""; -$XFERS_graph=$graph_header.""; -$SALEPCT_graph=$graph_header.""; -$SALE_graph=$graph_header.""; -$DROP_graph=$graph_header.""; -$OTHER_graph=$graph_header.""; ########################### $stmt="select user,count(*) from ".$vicidial_xfer_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' and campaign_id='" . mysqli_real_escape_string($link, $group) . "' and user is not null group by user;"; @@ -617,37 +613,87 @@ $ASCII_text.="+--------------------------+--------+--------+------+------+------ $CSV_fronter_footer.="\""._QXZ("TOTAL FRONTERS").": $TOTagents\",\"$TOTcalls\",\"$totSpct%\",\"$TOTsales\",\"$totDROP\",\"$totOTHER\"\n"; $CSV_fronter_footer.="\""._QXZ("Average time in Queue for customers").": $AVGwait\"\n\n\n"; - for ($d=0; $d"; - $SALEPCT_graph.=" "; - $SALE_graph.=" "; - $DROP_graph.=" "; - $OTHER_graph.=" "; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("FCSF_XFERSdata|1|XFERS|integer|", "FCSF_SALEPCTdata|2|SALE %|percent|", "FCSF_SALESdata|3|SALES|integer|", "FCSF_DROPSdata|4|DROPS|integer|", "FCSF_OTHERdata|5|OTHER|integer|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $XFERS_graph.="
    "._QXZ("FRONTER STATS")."
    "._QXZ("AGENT").""._QXZ("XFERS")."
    "._QXZ("SALE")." %
    "._QXZ("SALE")."
    "._QXZ("DROP")."
    "._QXZ("OTHER")."
    ".$graph_stats[$d][1]."
    ".$graph_stats[$d][0]."".$graph_stats[$d][2]."
    ".$graph_stats[$d][0]."".$graph_stats[$d][3]."
    ".$graph_stats[$d][0]."".$graph_stats[$d][4]."
    ".$graph_stats[$d][0]."".$graph_stats[$d][5]."
    "._QXZ("TOTAL").": $current_graph_total
    "._QXZ("TOTAL").":".trim($TOTcalls)."
    "; - $SALEPCT_graph.=""._QXZ("TOTAL").":".trim($totSpct)."%"; - $SALE_graph.=""._QXZ("TOTAL").":".trim($TOTsales).""; - $DROP_graph.=""._QXZ("TOTAL").":".trim($totDROP).""; - $OTHER_graph.=""._QXZ("TOTAL").":".trim($totOTHER).""; - $JS_onload.="\tDrawFronterGraph('XFERS', '1');\n"; - $JS_text.="function DrawFronterGraph(graph, th_id) {\n"; - $JS_text.=" var XFERS_graph=\"$XFERS_graph\";\n"; - $JS_text.=" var SALEPCT_graph=\"$SALEPCT_graph\";\n"; - $JS_text.=" var SALE_graph=\"$SALE_graph\";\n"; - $JS_text.=" var DROP_graph=\"$DROP_graph\";\n"; - $JS_text.=" var OTHER_graph=\"$OTHER_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=5; i++) {\n"; - $JS_text.=" var cellID=\"frontergraph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"frontergraph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('fronter_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $GRAPH_text.=$GRAPH; + + $graph_count=count($graph_array); + $graph_title=_QXZ("FRONTER STATS"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas; + + ############################## ######### CLOSER STATS @@ -678,15 +724,6 @@ $max_drops=1; $max_other=1; $max_sales2=1; $max_conv_pct=1; -$GRAPH="

    "; -$GRAPH.=""; -$GRAPH.="
    "._QXZ("CALLS").""._QXZ("SALE")."S"._QXZ("DROP").""._QXZ("OTHER").""._QXZ("CONV")." %

     


    "; -$graph_header=""; -$CALLS_graph=$graph_header.""; -$SALES_graph=$graph_header.""; -$DROP_graph=$graph_header.""; -$OTHER_graph=$graph_header.""; -$CONVPCT_graph=$graph_header.""; ########################### $stmt="select user,count(*) from ".$vicidial_closer_log_table." where call_date >= '$query_date_BEGIN' and call_date <= '$query_date_END' and campaign_id='" . mysqli_real_escape_string($link, $group) . "' and user is not null group by user;"; @@ -835,37 +872,85 @@ $ASCII_text.="+--------------------------+--------+------+------+------+-------+ $CSV_closer_footer.="\""._QXZ("TOTAL CLOSERS").": $TOTagents\",\"$TOTcalls\",\"$totA1\",\"$totDROP\",\"$totOTHER\",\"$TOTsales\",\"$totCpct%\"\n"; - for ($d=0; $d"; - $SALES_graph.=" "; - $DROP_graph.=" "; - $OTHER_graph.=" "; - $CONVPCT_graph.=" "; + # USE THIS FOR multiple graphs, use pipe-delimited array elements, dataset_name|index|link_name + $multigraph_text=""; + $graph_id++; + $graph_array=array("FCSC_CALLSdata|1|CALLS|integer|", "FCSC_SALESdata|2|SALES|integer|", "FCSC_DROPSdata|3|DROPS|integer|", "FCSC_OTHERdata|4|OTHER|integer|", "FCSC_CONVPCTdata|5|CONV %|percent|"); + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." \n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" \n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $CALLS_graph.="
    "._QXZ("CLOSER STATS")."
    "._QXZ("AGENT").""._QXZ("CALLS")."
    "._QXZ("SALES")."
    "._QXZ("DROP")."
    "._QXZ("OTHER")."
    "._QXZ("CONV")." %
    ".$graph_stats[$d][1]."
    ".$graph_stats[$d][0]."".$graph_stats[$d][2]."
    ".$graph_stats[$d][0]."".$graph_stats[$d][3]."
    ".$graph_stats[$d][0]."".$graph_stats[$d][4]."
    ".$graph_stats[$d][0]."".$graph_stats[$d][5]."%
    "._QXZ("TOTAL").": $current_graph_total
    "._QXZ("TOTAL").":".trim($TOTcalls)."
    "; - $SALES_graph.=""._QXZ("TOTAL").":".trim($TOTsales).""; - $DROP_graph.=""._QXZ("TOTAL").":".trim($totDROP).""; - $OTHER_graph.=""._QXZ("TOTAL").":".trim($totOTHER).""; - $CONVPCT_graph.=""._QXZ("TOTAL").":".trim($totCpct)."%"; - $JS_onload.="\tDrawCloserGraph('CALLS', '1');\n"; - $JS_text.="function DrawCloserGraph(graph, th_id) {\n"; - $JS_text.=" var CALLS_graph=\"$CALLS_graph\";\n"; - $JS_text.=" var SALES_graph=\"$SALES_graph\";\n"; - $JS_text.=" var DROP_graph=\"$DROP_graph\";\n"; - $JS_text.=" var OTHER_graph=\"$OTHER_graph\";\n"; - $JS_text.=" var CONVPCT_graph=\"$CONVPCT_graph\";\n"; - $JS_text.="\n"; - $JS_text.=" for (var i=1; i<=5; i++) {\n"; - $JS_text.=" var cellID=\"closergraph\"+i;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#DDDDDD';\n"; - $JS_text.=" }\n"; - $JS_text.=" var cellID=\"closergraph\"+th_id;\n"; - $JS_text.=" document.getElementById(cellID).style.backgroundColor='#999999';\n"; - $JS_text.=" var graph_to_display=eval(graph+\"_graph\");\n"; - $JS_text.=" document.getElementById('closer_graph').innerHTML=graph_to_display;\n"; - $JS_text.="}\n"; - $GRAPH_text.=$GRAPH; + + $graph_count=count($graph_array); + $graph_title=_QXZ("CLOSER STATS"); + include("graphcanvas.inc"); + $GRAPH_text.=$graphCanvas; $ENDtime = date("U"); @@ -912,9 +997,9 @@ else $JS_text.="\n"; echo $HTML_head; - echo $JS_text; require("admin_header.php"); echo $HTML_text; + echo $JS_text; } #$CSV_report=fopen("fcstats.csv", "w"); diff --git a/agc_2-X/trunk/www/vicidial/graph_color_schemas.inc b/agc_2-X/trunk/www/vicidial/graph_color_schemas.inc new file mode 100644 index 00000000..5e22fc61 --- /dev/null +++ b/agc_2-X/trunk/www/vicidial/graph_color_schemas.inc @@ -0,0 +1,101 @@ + 0) { + $color_row=mysqli_fetch_array($color_rslt); + + $backgroundColor=array("$color_row[std_row1_background]", "$color_row[std_row2_background]", "$color_row[std_row3_background]", "$color_row[std_row4_background]", "$color_row[std_row5_background]"); + array_filter($backgroundColor); + for ($ci=0; $ci diff --git a/agc_2-X/trunk/www/vicidial/graphcanvas.inc b/agc_2-X/trunk/www/vicidial/graphcanvas.inc new file mode 100644 index 00000000..86991313 --- /dev/null +++ b/agc_2-X/trunk/www/vicidial/graphcanvas.inc @@ -0,0 +1,93 @@ +"; +$graphCanvas.="\n"; +$graphCanvas.=" \n"; +if ($graph_count>1) { + $graphCanvas.=" \n"; + for ($q=0; $q<$graph_count; $q++) { + $graph_info=explode("|", $graph_array[$q]); + $link_name=$graph_info[2]; + $graphCanvas.=""; + } + $graphCanvas.=" \n"; +} + +$graphCanvas.=" \n"; +$graphCanvas.="
    "._QXZ("$graph_title")."
    "._QXZ("$link_name")."
    \n"; +for ($q=0; $q<$graph_count; $q++) { + + # SET GRAPH size FOR READABILITY + if (file_exists('options.php')) + { + require('options.php'); + $init_height=$graph_canvas_size; # Chart has a minimum height/width of 600 by default + } + else + { + $init_height=600; + } + + $entry_width=($init_width<20 ? 20 : ($init_width>50 ? 50 : $init_width)); + $init_width=(($graph_count*$entry_width)<$init_height ? $init_height : ($graph_count*$entry_width)); + + $graph_info=explode("|", $graph_array[$q]); + $dataset_name=$graph_info[0]; + $dataset_type=$graph_info[3]; + + switch($dataset_type) { + case "time": + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $chart_options="options: { legend: { display: false }},"; + break; + } + + + $graphCanvas.=""; + $graphCanvas.=""; + $graphCanvas.=$graph_totals_array[$q]; + $graphCanvas.="\n"; +/* + $graphCanvas.="\n"; + $graphCanvas.="\n"; + $graphCanvas.="\n"; + $graphCanvas.="\n"; + +var h = Math.floor(d / 3600); var m = Math.floor(d % 3600 / 60); var s = Math.floor(d % 3600 % 60); return ((h > 0 ? h + ":" + (m < 10 ? "0" : "") : "") + m + ":" + (s < 10 ? "0" : "") + s); + + type: 'pie', options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; var label = data.labels[tooltipItem.index]; var percentage = Math.round(value / totalSessions * 100); return label + ' ' + percentage + '%';}}},}, data: topBrowsers + */ + $graphCanvas.="\n"; + $graphCanvas.="\n"; + $graphCanvas.="\n"; + $graphCanvas.="\n"; + $graphCanvas.="\n"; + + $graphCanvas.="\n"; + $graphCanvas.=""; + $graphCanvas.=""; + $graphCanvas.=""; + $graphCanvas.=""; + $graphCanvas.="
    "; + $graphCanvas.="
    "; + $graphCanvas.="
    "; +} +$graphCanvas.="
    \n"; +$graphCanvas.="\n\n"; +?> + + \ No newline at end of file diff --git a/agc_2-X/trunk/www/vicidial/options-example.php b/agc_2-X/trunk/www/vicidial/options-example.php index 8fa316a6..91919c15 100644 --- a/agc_2-X/trunk/www/vicidial/options-example.php +++ b/agc_2-X/trunk/www/vicidial/options-example.php @@ -20,6 +20,7 @@ # 150909-1417 - Added $active_only_default_campaigns option for admin.php # 160102-1249 - Added htmlconvert option for modify lead pages # 160106-1321 - Added disable_user_group_bulk_change option +# 160715-0752 - Added graph_canvas_size option for HTML reports # # used by the realtime_report.php script @@ -97,4 +98,7 @@ $htmlconvert=1; # disable the user_group_bulk_change.php utility $disable_user_group_bulk_change=0; +# canvas size in pixels for Chartjs-style graphs (width and height) +$graph_canvas_size=600; + ?> diff --git a/agc_2-X/trunk/www/vicidial/timeclock_report.php b/agc_2-X/trunk/www/vicidial/timeclock_report.php index 4ad12c08..f14be2a5 100644 --- a/agc_2-X/trunk/www/vicidial/timeclock_report.php +++ b/agc_2-X/trunk/www/vicidial/timeclock_report.php @@ -26,6 +26,7 @@ # 140328-0005 - Converted division calculations to use MathZDC function # 141114-0028 - Finalized adding QXZ translation to all admin files # 141230-0948 - Added code for on-the-fly language translations display +# 160714-2348 - Added and tested ChartJS features for more aesthetically appealing graphs # $startMS = microtime(); @@ -318,12 +319,16 @@ $HEADER.=" .header_white {font-size: 14px; font-family: sans-serif; font-weig $HEADER.=" .data_records {font-size: 12px; font-family: sans-serif; color: black}\n"; $HEADER.=" .data_records_fix {font-size: 12px; font-family: monospace; color: black}\n"; $HEADER.=" .data_records_fix_small {font-size: 9px; font-family: monospace; color: black}\n"; -$HEADER.="\n"; +$HEADER.="\n"; $HEADER.="-->\n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; $HEADER.="\n"; +require("chart_button.php"); +$HEADER.="\n"; +$HEADER.="\n"; + $HEADER.="\n"; $HEADER.="\n"; @@ -601,24 +606,89 @@ else } if ($high_ct<1) {$high_ct*=10;} $MAIN.="</PRE>\n"; - $MAIN.="<table cellspacing=\"0\" cellpadding=\"0\" summary=\"CALL HANGUP REASON STATS\" class=\"horizontalgraph\">\n"; - $MAIN.=" <caption align=\"top\">"._QXZ("USER TIMECLOCK DETAILS")."<br /><font size='-1'>"._QXZ("Time range").": $query_date to $end_date<br/>"._QXZ("These totals do NOT include any active sessions")."</font><br /></caption>\n"; - $MAIN.=" <tr>\n"; - $MAIN.=" <th class=\"thgraph\" scope=\"col\">"._QXZ("USER")." </th>\n"; - $MAIN.=" <th class=\"thgraph\" scope=\"col\">"._QXZ("HOURS")." </th>\n"; - $MAIN.=" </tr>\n"; - for ($i=0; $i<count($ct_ary); $i++) { - if ($i==0) {$class=" first";} else if (($i+1)==count($ct_ary)) {$class=" last";} else {$class="";} - $MAIN.=" <tr>\n"; - $MAIN.=" <td class=\"chart_td$class\">".$ct_ary[$i][0]."</td>\n"; - $MAIN.=" <td class=\"chart_td value$class\"><img src=\"images/bar.png\" alt=\"\" width=\"".round(MathZDC(400*$ct_ary[$i][1], $high_ct))."\" height=\"16\" />".$ct_ary[$i][1]."</td>\n"; - $MAIN.=" </tr>\n"; + + $JS_text="<script language='Javascript'>\n"; + ######### + $graph_array=array("TCdata|||decimal|"); + $graph_id++; + $default_graph="bar"; # Graph that is initally displayed when page loads + include("graph_color_schemas.inc"); + + $graph_totals_array=array(); + $graph_totals_rawdata=array(); + for ($q=0; $q<count($graph_array); $q++) { + $graph_info=explode("|", $graph_array[$q]); + $current_graph_total=0; + $dataset_name=$graph_info[0]; + $dataset_index=$graph_info[1]; + $dataset_type=$graph_info[3]; + if ($q==0) {$preload_dataset=$dataset_name;} # Used below to load initial graph + + $JS_text.="var $dataset_name = {\n"; + # $JS_text.="\ttype: \"\",\n"; + # $JS_text.="\t\tdata: {\n"; + $datasets="\t\tdatasets: [\n"; + $datasets.="\t\t\t{\n"; + $datasets.="\t\t\t\tlabel: \"\",\n"; + $datasets.="\t\t\t\tfill: false,\n"; + + $labels="\t\tlabels:["; + $data="\t\t\t\tdata: ["; + $graphConstantsA="\t\t\t\tbackgroundColor: ["; + $graphConstantsB="\t\t\t\thoverBackgroundColor: ["; + $graphConstantsC="\t\t\t\thoverBorderColor: ["; + for ($d=0; $d<count($ct_ary); $d++) { + $labels.="\"".$ct_ary[$d][0]."\","; + $data.="\"".$ct_ary[$d][1]."\","; + $current_graph_total+=$ct_ary[$d][1]; + $bgcolor=$backgroundColor[($d%count($backgroundColor))]; + $hbgcolor=$hoverBackgroundColor[($d%count($hoverBackgroundColor))]; + $hbcolor=$hoverBorderColor[($d%count($hoverBorderColor))]; + $graphConstantsA.="\"$bgcolor\","; + $graphConstantsB.="\"$hbgcolor\","; + $graphConstantsC.="\"$hbcolor\","; + } + $graphConstantsA.="],\n"; + $graphConstantsB.="],\n"; + $graphConstantsC.="],\n"; + $labels=preg_replace('/,$/', '', $labels)."],\n"; + $data=preg_replace('/,$/', '', $data)."],\n"; + + $graph_totals_rawdata[$q]=$current_graph_total; + switch($dataset_type) { + case "time": + $graph_totals_array[$q]=" <caption align=\"bottom\">"._QXZ("TOTAL")." - ".sec_convert($current_graph_total, 'H')." </caption>\n"; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = Math.round(data.datasets[0].data[tooltipItem.index]); return value.toHHMMSS();}}}, legend: { display: false }},"; + break; + case "percent": + $graph_totals_array[$q]=""; + $chart_options="options: {tooltips: {callbacks: {label: function(tooltipItem, data) {var value = data.datasets[0].data[tooltipItem.index]; return value + '%';}}}, legend: { display: false }},"; + break; + default: + $graph_totals_array[$q]=" <caption align=\"bottom\">"._QXZ("TOTAL").": $current_graph_total</caption>\n"; + $chart_options="options: { legend: { display: false }},"; + break; + } + + $datasets.=$data; + $datasets.=$graphConstantsA.$graphConstantsB.$graphConstantsC.$graphConstants; # SEE TOP OF SCRIPT + $datasets.="\t\t\t}\n"; + $datasets.="\t\t]\n"; + $datasets.="\t}\n"; + + $JS_text.=$labels.$datasets; + # $JS_text.="}\n"; + # $JS_text.="prepChart('$default_graph', $graph_id, $q, $dataset_name);\n"; + $JS_text.="var main_ctx = document.getElementById(\"CanvasID".$graph_id."_".$q."\");\n"; + $JS_text.="var GraphID".$graph_id."_".$q." = new Chart(main_ctx, {type: '$default_graph', $chart_options data: $dataset_name});\n"; } - $MAIN.=" <tr>\n"; - $MAIN.=" <th class=\"thgraph\" scope=\"col\">"._QXZ("TOTAL HOURS").":</th>\n"; - $MAIN.=" <th class=\"thgraph\" scope=\"col\">".trim($TOThours)."</th>\n"; - $MAIN.=" </tr>\n"; - $MAIN.="</table>\n"; + + $graph_count=count($graph_array); + $graph_title=_QXZ("USER TIMECLOCK DETAILS"); + include("graphcanvas.inc"); + $MAIN.=$graphCanvas; + $JS_text.="</script>\n"; + $MAIN.="<PRE>\n"; ########################### } @@ -650,7 +720,7 @@ $MAIN.="</BODY></HTML>\n"; } else { echo $HEADER; require("admin_header.php"); - echo $MAIN; + echo $MAIN.$JS_text; } if ($db_source == 'S') diff --git a/agc_2-X/trunk/www/vicidial/vicidial_chart_functions.js b/agc_2-X/trunk/www/vicidial/vicidial_chart_functions.js new file mode 100644 index 00000000..ba42e766 --- /dev/null +++ b/agc_2-X/trunk/www/vicidial/vicidial_chart_functions.js @@ -0,0 +1,81 @@ +/* +Vicidial chart functions - put any and all Javascript functions +dealing with charts/graphs for Vicidial here. +var mainChart=null; +function drawChart(chart_type, graph_id, dataset_name, graph_name){ + var canvasID="GraphDisplay"+graph_id; + var graphName="GraphID"+graph_id; + + if(eval(graphName)==null){ + // do nothing + } else { + graphName.destroy(); + // main_data.type = chart_type; + // alert(main_data.type); + //mainChart.type = chart_type; // Would update the first dataset's value of 'March' to be 50 + //mainChart.update(); + //alert(mainChart.type); + + } + dataset_name.type = chart_type; + dataset_name.data.datasets.forEach(function(dataset) { + dataset.type = chart_type + }); + + var main_ctx = document.getElementById(canvasID).getContext("2d"); + eval(graphName) = new Chart(main_ctx, dataset_name); +} +*/ + +function ToggleSpan(span_family, selected_span, span_count) { + if (!span_count || span_count<1) { + return false; + } else { + for (var j=0; j<span_count; j++) { + var spanID="SpanID"+span_family+"_"+j; + var linkID="LinkID"+span_family+"_"+j; + if (j==selected_span || j==span_count) { + document.getElementById(spanID).style.display = 'block'; + document.getElementById(linkID).className='thgraph selected_grey_graph_cell'; + } else { + document.getElementById(spanID).style.display = 'none'; + document.getElementById(linkID).className='thgraph grey_graph_cell'; + } + } + } +} + +var main_ctx=''; + + +Number.prototype.toHHMMSS = function () { + var sec_num = parseInt(this, 10); // don't forget the second param + var hours = Math.floor(sec_num / 3600); + var minutes = Math.floor((sec_num - (hours * 3600)) / 60); + var seconds = sec_num - (hours * 3600) - (minutes * 60); + + if (hours > 0) { + if (hours < 10) {hours = "0"+hours;} + hours=hours+':'; + } else { + hours=''; + } + if (minutes < 10) {minutes = "0"+minutes;} + if (seconds < 10) {seconds = "0"+seconds;} + return hours+minutes+':'+seconds; +} +/* + +function prepChart(graph_type, graph_id, graph_count, dataset_name){ + if (graph_type!="<?php echo $allowed_graph; ?>" && "<?php echo $allowed_graph; ?>"!="ALL") {alert("This graph type is not allowed."); return false;} + var canvasID="CanvasID"+graph_id+"_"+graph_count; + var graphID="GraphID"+graph_id+"_"+graph_count; + + dataset_name.type = graph_type; + dataset_name.data.datasets.forEach(function(dataset) { + dataset.type = graph_type + }); + + main_ctx = document.getElementById(canvasID).getContext("2d"); +} +*/ \ No newline at end of file