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 / services / revenue / count.php
vikappointments / admin / layouts / statistics / widgets / services / revenue Last commit date
chart.php 5 days ago count.php 5 days ago index.html 5 days ago
count.php
268 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 services-revenue-count">
38 <canvas></canvas>
39 </div>
40
41 <div class="widget-floating-box">
42
43 <span class="badge badge-info pull-left range"></span>
44
45 <span class="badge badge-info pull-left datefrom" style="margin-right: 4px;"></span>
46 <span class="badge badge-important pull-left dateto"></span>
47
48 </div>
49
50 <script>
51
52 /**
53 * Defines a pool of charts, if undefined.
54 *
55 * @var object
56 */
57 if (typeof SERVICES_REVENUE_COUNT === 'undefined') {
58 var SERVICES_REVENUE_COUNT = {};
59 }
60
61 // init callbacks pool in case the caller didn't declare it
62 if (typeof WIDGET_CALLBACKS === 'undefined') {
63 var WIDGET_CALLBACKS = {};
64 }
65
66 (function($) {
67 'use strict';
68
69 /**
70 * Register callback to be executed after
71 * completing the update request.
72 *
73 * @param mixed widget The widget selector.
74 * @param mixed data The AJAX response.
75 * @param object config The widget configuration.
76 *
77 * @return void
78 */
79 WIDGET_CALLBACKS[<?php echo $widget->getID(); ?>] = (widget, data, config) => {
80 // get widget ID
81 var id = $(widget).attr('id');
82
83 // prepare chart data
84 var chartData = {
85 // dataset options
86 datasets: [{
87 // dataset values
88 data: [],
89 // dataset color
90 backgroundColor: [],
91 hoverBorderColor: [],
92 }],
93 // dataset labels
94 labels: [],
95 };
96
97 $.each(data, (k, service) => {
98 var label = service.name;
99
100 <?php
101 if (isset($data))
102 {
103 ?>
104 // display total if we are printing the document
105 var sublabel = service.total;
106
107 if (config.valuetype == 'total') {
108 // format value as currency
109 sublabel = VAPCurrency.getInstance().format(service.total);
110 }
111
112 label += ' (' + sublabel + ')';
113 <?php
114 }
115 ?>
116
117 // push appointments total
118 chartData.datasets[0].data.push(service.total);
119 // hide highlight on hover
120 chartData.datasets[0].hoverBorderColor.push('#0000');
121 // push label
122 chartData.labels.push(label);
123 // fetch background color
124 chartData.datasets[0].backgroundColor.push('#' + service.color);
125 });
126
127 // prepare chart configuration
128 var options = {
129 // hide legend
130 legend: {
131 // draw legend only if we are printing the document
132 display: <?php echo isset($data) ? 'true' : 'false'; ?>,
133 },
134 // tooltip handling
135 tooltips: {
136 // tooltip callbacks are used to customize default texts
137 callbacks: {
138 // format the tooltip text displayed when hovering a point
139 label: (tooltipItem, data) => {
140 // keep default label
141 var label = data.labels[tooltipItem.index] || '';
142
143 <?php
144 if (!isset($data))
145 {
146 ?>
147 // display formatted appointments only if we are NOT printing the document
148 if (label) {
149 label += ': ';
150
151 var value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
152
153 // format as currency in case of earning
154 if (config.valuetype == 'total') {
155 label += VAPCurrency.getInstance().format(value);
156 } else {
157 var count = parseInt(value);
158 var langk = 'VAP_N_RESERVATIONS';
159
160 // format label by fetching singular/plural form
161 if (count == 1) {
162 label += Joomla.JText._(langk + '_1');
163 } else {
164 label += Joomla.JText._(langk).replace(/%d/, count);
165 }
166 }
167 }
168 <?php
169 }
170 ?>
171
172 return ' ' + label;
173 },
174 // change label colors because, by default, the legend background is blank
175 labelColor: (tooltipItem, chart) => {
176 // get tooltip item meta data
177 var meta = chart.data.datasets[tooltipItem.datasetIndex];
178
179 return {
180 // use white border
181 borderColor: 'rgb(0,0,0)',
182 // use same item background color
183 backgroundColor: meta.backgroundColor[tooltipItem.index],
184 };
185 },
186 },
187 },
188 animation: {
189 // unset duration in case we are exporting the chart
190 duration: <?php echo isset($data) ? 0 : 1000; ?>,
191 },
192 // the percentage of the chart that is cut out of the middle
193 cutoutPercentage: 70,
194 };
195
196 // init chart from scratch if NULL
197 if (!SERVICES_REVENUE_COUNT.hasOwnProperty(id)) {
198 // get 2D canvas for DOUGHNUT chart
199 var canvas = $(widget).find('canvas')[0];
200 var ctx = canvas.getContext('2d');
201
202 // init chart from scratch if undefined
203 SERVICES_REVENUE_COUNT[id] = new Chart(ctx, {
204 type: 'doughnut',
205 data: chartData,
206 options: options,
207 });
208 } else {
209 // update chart data
210 SERVICES_REVENUE_COUNT[id].data = chartData;
211
212 // update chart options
213 SERVICES_REVENUE_COUNT[id].options = options;
214
215 // refresh chart
216 SERVICES_REVENUE_COUNT[id].update();
217 }
218
219 // update badges
220 if (config.datefrom || config.dateto) {
221 // at least a date was selected, show "from" and "to"
222 $(widget).find('.badge.datefrom').text(config.datefrom ? config.datefrom : '--');
223 $(widget).find('.badge.dateto').text(config.dateto ? config.dateto : '--');
224
225 // hide default range
226 $(widget).find('.badge.range').text('');
227 } else {
228 // hide both empty dates
229 $(widget).find('.badge.datefrom').text('');
230 $(widget).find('.badge.dateto').text('');
231
232 // retrieve selected range text
233 var range = $('select[name="<?php echo $widget->getName() . '_' . $widget->getID(); ?>_range"]')
234 .find('option[value="' + config.range + '"]')
235 .text();
236
237 // show range
238 $(widget).find('.badge.range').text(range);
239 }
240 }
241
242 <?php
243
244 ////////////////////////
245 ///// EXPORT UTILS /////
246 ////////////////////////
247
248 if (isset($data))
249 {
250 ?>
251 $(function() {
252 // auto-invoke callback on page loading completion
253 WIDGET_CALLBACKS[<?php echo $widget->getID(); ?>](
254 // exported assume, there should be only one widget displayed
255 $('.services-revenue-count'),
256 // JSON-encode the passed chart data
257 <?php echo json_encode($data); ?>,
258 // JSON-encode the widget configuration
259 <?php echo json_encode($widget->getOptions()); ?>
260 );
261 });
262 <?php
263 }
264 ?>
265 })(jQuery);
266
267 </script>
268