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 / appointments / weekdays.php
vikappointments / admin / layouts / statistics / widgets / customers / appointments Last commit date
chart.php 6 days ago index.html 6 days ago weekdays.php 6 days ago
weekdays.php
253 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 * @var mixed $data The chart data to immediately display.
19 */
20 extract($displayData);
21
22 // include chart JS dependencies
23 JHtml::fetch('vaphtml.assets.chartjs');
24
25 // get list of preset colors
26 $colors = JHtml::fetch('vaphtml.color.preset', $list = true, $group = false);
27
28 JText::script('VAP_N_RESERVATIONS');
29 JText::script('VAP_N_RESERVATIONS_1');
30
31 ?>
32
33 <div class="canvas-align-bottom customers-weekdays-chart">
34 <canvas></canvas>
35 </div>
36
37 <div class="no-results" style="display:none;">
38 <?php echo VAPApplication::getInstance()->alert(JText::translate('JGLOBAL_NO_MATCHING_RESULTS')); ?>
39 </div>
40
41 <script>
42
43 /**
44 * Defines a pool of charts, if undefined.
45 *
46 * @var object
47 */
48 if (typeof CUSTOMERS_WEEKDAYS_CHARTS === 'undefined') {
49 var CUSTOMERS_WEEKDAYS_CHARTS = {};
50 }
51
52 // init callbacks pool in case the caller didn't declare it
53 if (typeof WIDGET_CALLBACKS === 'undefined') {
54 var WIDGET_CALLBACKS = {};
55 }
56
57 (function($) {
58 'use strict';
59
60 // get default system preset of colors
61 const colorsPreset = <?php echo json_encode($colors); ?>;
62
63 /**
64 * Register callback to be executed after
65 * completing the update request.
66 *
67 * @param mixed widget The widget selector.
68 * @param mixed data The AJAX response.
69 * @param object config The widget configuration.
70 *
71 * @return void
72 */
73 WIDGET_CALLBACKS[<?php echo $widget->getID(); ?>] = (widget, data, config) => {
74 // get widget ID
75 var id = $(widget).attr('id');
76
77 if (!data) {
78 // show "no results" box in case of empty list
79 $(widget).find('.customers-weekdays-chart').hide();
80 $(widget).find('.no-results').show();
81
82 // do not need to go ahead
83 return false;
84 }
85
86 // hide "no results" box if there is at least a status
87 $(widget).find('.no-results').hide();
88 $(widget).find('.customers-weekdays-chart').show();
89
90 // start from first position of the preset
91 let colorIndex = 0;
92
93 // prepare chart data
94 var chartData = {
95 labels: Object.keys(data),
96 datasets: {},
97 };
98
99 let suggestedMax = 0;
100
101 // iterate all dates
102 $.each(data, (lbl, customers) => {
103 // iterate all coupons
104 $.each(customers, (id_user, customer) => {
105 // check whether we already created the dataset for this coupon code
106 if (!chartData.datasets.hasOwnProperty(id_user)) {
107 // get progressive color
108 let color = colorsPreset[colorIndex++ % colorsPreset.length];
109
110 chartData.datasets[id_user] = {
111 // the label string that appears when hovering the mouse above the lines intersection points
112 label: customer.name,
113 // the background color drawn behind the line (99 = 60% opacity)
114 backgroundColor: "#" + color + "99",
115 // the fill color of the line
116 borderColor: "#" + color,
117 // the line dataset
118 data: [],
119 };
120 }
121
122 // include value within the dataset
123 chartData.datasets[id_user].data.push(customer.total);
124
125 // take maximum amount
126 suggestedMax = Math.max(suggestedMax, parseInt(customer.total) + 1);
127 });
128 });
129
130 // convert datasets into a linear array
131 chartData.datasets = Object.values(chartData.datasets);
132
133 // init chart from scratch if NULL
134 if (!CUSTOMERS_WEEKDAYS_CHARTS.hasOwnProperty(id)) {
135 // prepare chart configuration
136 var options = {
137 legend: {
138 // draw legend only if explicitly requested
139 display: <?php echo !empty($legend) ? 'true' : 'false'; ?>,
140 },
141 // axes handling
142 scales: {
143 // Y Axis properties
144 yAxes: [{
145 ticks: {
146 // make sure the chart starts at 0
147 beginAtZero: true,
148 // ignore real numbers
149 precision: 0,
150 // increase ceil by one for a better readability
151 suggestedMax: suggestedMax,
152 },
153 }],
154 },
155 // tooltip handling
156 tooltips: {
157 // tooltip callbacks are used to customize default texts
158 callbacks: {
159 // format the tooltip text displayed when hovering a point
160 label: (item, data) => {
161 // extract customer name from dataset
162 let customer = data.datasets[item.datasetIndex].label;
163
164 let label = '';
165
166 var count = parseInt(item.value);
167 var langk = 'VAP_N_RESERVATIONS';
168
169 // format label by fetching singular/plural form
170 if (count == 1) {
171 label = Joomla.JText._(langk + '_1');
172 } else {
173 label = Joomla.JText._(langk).replace(/%d/, count);
174 }
175
176 if (customer) {
177 label = customer + ': ' + label;
178 }
179
180 // create label in the form "COUPON: TOTAL"
181 return ' ' + label;
182 },
183 // change label colors because, by default, the legend background is blank
184 labelColor: (tooltipItem, chart) => {
185 // get tooltip item meta data
186 var meta = chart.data.datasets[tooltipItem.datasetIndex];
187
188 return {
189 // use white border
190 borderColor: 'rgb(0,0,0)',
191 // use same item background color
192 backgroundColor: meta.borderColor,
193 };
194 },
195 },
196 },
197 animation: {
198 // unset duration in case we are exporting the chart
199 duration: <?php echo isset($data) ? 0 : 1000; ?>,
200 },
201 };
202
203 // get 2D canvas for LINE chart
204 var canvas = $(widget).find('canvas')[0];
205 var ctx = canvas.getContext('2d');
206
207 // init chart from scratch if undefined
208 CUSTOMERS_WEEKDAYS_CHARTS[id] = new Chart(ctx, {
209 type: 'bar',
210 data: chartData,
211 options: options,
212 });
213 }
214 // otherwise update labels and values
215 else {
216 // update chart data
217 CUSTOMERS_WEEKDAYS_CHARTS[id].data = chartData;
218
219 // refresh suggested max
220 CUSTOMERS_WEEKDAYS_CHARTS[id].options.scales.yAxes[0].ticks.suggestedMax = suggestedMax;
221
222 // refresh chart
223 CUSTOMERS_WEEKDAYS_CHARTS[id].update();
224 }
225 }
226
227 <?php
228
229 ////////////////////////
230 ///// EXPORT UTILS /////
231 ////////////////////////
232
233 if (isset($data))
234 {
235 ?>
236 $(function() {
237 // auto-invoke callback on page loading completion
238 WIDGET_CALLBACKS[<?php echo $widget->getID(); ?>](
239 // exported assume, there should be only one widget displayed
240 $('.customers-weekdays-chart'),
241 // JSON-encode the passed chart data
242 <?php echo json_encode($data); ?>,
243 // JSON-encode the widget configuration
244 <?php echo json_encode($widget->getOptions()); ?>
245 );
246 });
247 <?php
248 }
249 ?>
250 })(jQuery);
251
252 </script>
253