PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / admin / layouts / statistics / widgets / customers / overall.php
vikappointments / admin / layouts / statistics / widgets / customers Last commit date
appointments 5 days ago preferred 5 days ago status 5 days ago index.html 5 days ago overall.php 5 days ago
overall.php
299 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * Layout variables
16 * -----------------
17 * @var VAPStatisticsWidget $widget The instance of the widget to be displayed.
18 */
19 extract($displayData);
20
21 // include chart JS dependencies
22 JHtml::fetch('vaphtml.assets.chartjs');
23
24 JText::script('VAP_N_RESERVATIONS');
25 JText::script('VAP_N_RESERVATIONS_1');
26
27 ?>
28
29 <style>
30
31 .canvas-align-center {
32 height: calc(100% - 20px) !important;
33 }
34
35 </style>
36
37 <div class="canvas-align-center customers-overall-chart">
38 <canvas></canvas>
39 </div>
40
41 <div class="no-results" style="display: none;">
42 <?php echo VAPApplication::getInstance()->alert(JText::translate('JGLOBAL_NO_MATCHING_RESULTS')); ?>
43 </div>
44
45 <div class="widget-floating-box">
46
47 <span class="badge badge-info pull-left range"></span>
48
49 <span class="badge badge-info pull-left datefrom" style="margin-right: 4px;"></span>
50 <span class="badge badge-important pull-left dateto"></span>
51
52 </div>
53
54 <script>
55
56 /**
57 * Defines a pool of charts, if undefined.
58 *
59 * @var object
60 */
61 if (typeof CUSTOMERS_OVERALL_CHART === 'undefined') {
62 var CUSTOMERS_OVERALL_CHART = {};
63 }
64
65 // init callbacks pool in case the caller didn't declare it
66 if (typeof WIDGET_CALLBACKS === 'undefined') {
67 var WIDGET_CALLBACKS = {};
68 }
69
70 (function($) {
71 'use strict';
72
73 /**
74 * Register callback to be executed after
75 * completing the update request.
76 *
77 * @param mixed widget The widget selector.
78 * @param mixed data The AJAX response.
79 * @param object config The widget configuration.
80 *
81 * @return void
82 */
83 WIDGET_CALLBACKS[<?php echo $widget->getID(); ?>] = (widget, data, config) => {
84 // get widget ID
85 var id = $(widget).attr('id');
86
87 if ($.isEmptyObject(data)) {
88 // show "no results" box in case of empty list
89 $(widget).find('.canvas-align-center.customers-overall-chart').hide();
90 $(widget).find('.no-results').show();
91
92 // we don't need to go ahead
93 return;
94 }
95
96 // hide "no results" box if there is at least a status
97 $(widget).find('.no-results').hide();
98 $(widget).find('.canvas-align-center.customers-overall-chart').show();
99
100 /**
101 * Create callback used to format the values displayed
102 * with the tooltips of the hovered points, according
103 * to the saved configuration.
104 *
105 * @param mixed item The item to display.
106 * @param mixed data The chart data.
107 *
108 * @return string The formatted value.
109 */
110 const formatPointTooltip = (item, data) => {
111 // keep default label
112 var label = data.labels[item.index] || '';
113
114 <?php
115 if (!isset($data))
116 {
117 ?>
118 if (label) {
119 label += ': ';
120 }
121
122
123 let value = data.datasets[item.datasetIndex].data[item.index];
124
125 // format as currency in case of earning
126 if (config.valuetype == 'total') {
127 label += VAPCurrency.getInstance().format(value);
128 }
129 // format number of orders
130 else
131 {
132 var count = parseInt(value);
133 var langk = 'VAP_N_RESERVATIONS';
134
135 // format label by fetching singular/plural form
136 if (count == 1) {
137 label += Joomla.JText._(langk + '_1');
138 } else {
139 label += Joomla.JText._(langk).replace(/%d/, count);
140 }
141 }
142 <?php
143 }
144 ?>
145
146 return ' ' + label;
147 }
148
149 // prepare chart data
150 var chartData = {
151 // dataset options
152 datasets: [{
153 // dataset values
154 data: [],
155 // dataset color
156 backgroundColor: [],
157 hoverBorderColor: [],
158 }],
159 // dataset labels
160 labels: [],
161 };
162
163 $.each(data, (id_user, customer) => {
164 var label = customer.name;
165
166 <?php
167 if (isset($data))
168 {
169 ?>
170 let value;
171
172 if (config.valuetype == 'total') {
173 value = VAPCurrency.getInstance().format(customer.total);
174 } else {
175 // display number of appointments if we are printing the document
176 value = customer.count;
177 }
178
179 label += ' (' + value + ')';
180 <?php
181 }
182 ?>
183
184 // push status count
185 chartData.datasets[0].data.push(customer[config.valuetype]);
186 // hide highlight on hover
187 chartData.datasets[0].hoverBorderColor.push('#0000');
188 // push label
189 chartData.labels.push(label);
190 // fetch background color
191 chartData.datasets[0].backgroundColor.push('#' + customer.color);
192 });
193
194 // init chart from scratch if NULL
195 if (!CUSTOMERS_OVERALL_CHART.hasOwnProperty(id)) {
196 // prepare chart configuration
197 var options = {
198 // hide legend
199 legend: {
200 // draw legend only if we are printing the document
201 display: <?php echo isset($data) ? 'true' : 'false'; ?>,
202 },
203 // tooltip handling
204 tooltips: {
205 // tooltip callbacks are used to customize default texts
206 callbacks: {
207 // format the tooltip text displayed when hovering a point
208 label: formatPointTooltip,
209 // change label colors because, by default, the legend background is blank
210 labelColor: (tooltipItem, chart) => {
211 // get tooltip item meta data
212 var meta = chart.data.datasets[tooltipItem.datasetIndex];
213
214 return {
215 // use white border
216 borderColor: 'rgb(0,0,0)',
217 // use same item background color
218 backgroundColor: meta.backgroundColor[tooltipItem.index],
219 };
220 },
221 },
222 },
223 animation: {
224 // unset duration in case we are exporting the chart
225 duration: <?php echo isset($data) ? 0 : 1000; ?>,
226 },
227 };
228
229 // get 2D canvas for DOUGHNUT chart
230 var canvas = $(widget).find('canvas')[0];
231 var ctx = canvas.getContext('2d');
232
233 // init chart from scratch if undefined
234 CUSTOMERS_OVERALL_CHART[id] = new Chart(ctx, {
235 type: 'pie',
236 data: chartData,
237 options: options,
238 });
239 } else {
240 // update chart data
241 CUSTOMERS_OVERALL_CHART[id].data = chartData;
242
243 // update format callbacks
244 CUSTOMERS_OVERALL_CHART[id].options.tooltips.callbacks.label = formatPointTooltip;
245
246 // refresh chart
247 CUSTOMERS_OVERALL_CHART[id].update();
248 }
249
250 // update badges
251 if (config.datefrom || config.dateto) {
252 // at least a date was selected, show "from" and "to"
253 $(widget).find('.badge.datefrom').text(config.datefrom ? config.datefrom : '--');
254 $(widget).find('.badge.dateto').text(config.dateto ? config.dateto : '--');
255
256 // hide default range
257 $(widget).find('.badge.range').text('');
258 } else {
259 // hide both empty dates
260 $(widget).find('.badge.datefrom').text('');
261 $(widget).find('.badge.dateto').text('');
262
263 // retrieve selected range text
264 var range = $('select[name="<?php echo $widget->getName() . '_' . $widget->getID(); ?>_range"]')
265 .find('option[value="' + config.range + '"]')
266 .text();
267
268 // show range
269 $(widget).find('.badge.range').text(range);
270 }
271 }
272
273 <?php
274
275 ////////////////////////
276 ///// EXPORT UTILS /////
277 ////////////////////////
278
279 if (isset($data))
280 {
281 ?>
282 $(function() {
283 // auto-invoke callback on page loading completion
284 WIDGET_CALLBACKS[<?php echo $widget->getID(); ?>](
285 // exported assume, there should be only one widget displayed
286 $('.customers-overall-chart'),
287 // JSON-encode the passed chart data
288 <?php echo json_encode($data); ?>,
289 // JSON-encode the widget configuration
290 <?php echo json_encode($widget->getOptions()); ?>
291 );
292 });
293 <?php
294 }
295 ?>
296 })(jQuery);
297
298 </script>
299