PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
← All changes | back/Helpers/global/chart.php +403 -342 10.1.4 → 11.1.0 View file →
@@ -1,7 +1,8 @@
1 1 <?php
2 +defined('ABSPATH') || die('Restricted Access');
2 3
3 -function acym_lineChart(array $dataMonth, array $dataDay, array $dataHour, bool $ajax = false): string
4 +function acym_lineChart(array $dataMonth, array $dataDay, array $dataHour, bool $ajax = false): void
4 5 {
5 6 acym_initializeChart();
6 7
7 8 $month = [];
@@ -8,11 +9,11 @@
8 9 $openMonth = [];
9 10 $clickMonth = [];
10 11
11 12 foreach ($dataMonth as $key => $data) {
12 - $month[] = '"'.$key.'"';
13 - $openMonth[] = '"'.$data['open'].'"';
14 - $clickMonth[] = '"'.$data['click'].'"';
13 + $month[] = $key;
14 + $openMonth[] = $data['open'];
15 + $clickMonth[] = $data['click'];
15 16 }
16 17
17 18 $day = [];
18 19 $openDay = [];
@@ -18,11 +19,11 @@
18 19 $openDay = [];
19 20 $clickDay = [];
20 21
21 22 foreach ($dataDay as $key => $data) {
22 - $day[] = '"'.$key.'"';
23 - $openDay[] = '"'.$data['open'].'"';
24 - $clickDay[] = '"'.$data['click'].'"';
23 + $day[] = $key;
24 + $openDay[] = $data['open'];
25 + $clickDay[] = $data['click'];
25 26 }
26 27
27 28 $hour = [];
28 29 $openHour = [];
@@ -28,17 +29,16 @@
28 29 $openHour = [];
29 30 $clickHour = [];
30 31
31 32 foreach ($dataHour as $key => $data) {
32 - $hour[] = '"'.$key.'"';
33 - $openHour[] = '"'.$data['open'].'"';
34 - $clickHour[] = '"'.$data['click'].'"';
33 + $hour[] = $key;
34 + $openHour[] = $data['open'];
35 + $clickHour[] = $data['click'];
35 36 }
36 37
37 - $randNumber = rand(1000, 9000);
38 + $randNumber = acym_rand(1000, 9000);
38 39 $idCanvas = 'acy_canvas_rand_id'.$randNumber;
39 40 $idLegend = 'acy_legend_rand_id'.$randNumber;
40 - $return = '';
41 41
42 42 $nbDataDay = count($dataDay);
43 43 $nbDataHour = count($dataHour);
44 44 $selectedChartHour = "";
@@ -60,176 +60,204 @@
60 60 $displayed = $month;
61 61 $clickDisplayed = $clickMonth;
62 62 $openDisplayed = $openMonth;
63 63 }
64 + ?>
64 65
66 + <div class="acym__chart__line__container">
67 + <div class="acym__chart__line__choose__by">
68 + <p class="acym__chart__line__choose__by__one <?php echo esc_attr($selectedChartMonth); ?>" onclick="acymChartLineUpdate(this, 'month')">
69 + <?php echo esc_html(acym_translation('ACYM_BY_MONTH')); ?>
70 + </p>
71 + <p class="acym__chart__line__choose__by__one <?php echo esc_attr($selectedChartDay); ?>" onclick="acymChartLineUpdate(this, 'day')">
72 + <?php echo esc_html(acym_translation('ACYM_BY_DAY')); ?>
73 + </p>
74 + <p class="acym__chart__line__choose__by__one <?php echo esc_attr($selectedChartHour); ?>" onclick="acymChartLineUpdate(this, 'hour')">
75 + <?php echo esc_html(acym_translation('ACYM_BY_HOUR')); ?>
76 + </p>
77 + </div>
78 + <div class="acym__chart__line__legend" id="<?php echo esc_attr($idLegend); ?>"></div>
79 + <canvas id="<?php echo esc_attr($idCanvas); ?>" height="400" width="400"></canvas>
80 + </div>
65 81
66 - $return .= '<div class="acym__chart__line__container">
67 - <div class="acym__chart__line__choose__by">
68 - <p class="acym__chart__line__choose__by__one '.$selectedChartMonth.'" onclick="acymChartLineUpdate(this, \'month\')">'.acym_translation('ACYM_BY_MONTH').'</p>
69 - <p class="acym__chart__line__choose__by__one '.$selectedChartDay.'" onclick="acymChartLineUpdate(this, \'day\')">'.acym_translation('ACYM_BY_DAY').'</p>
70 - <p class="acym__chart__line__choose__by__one '.$selectedChartHour.'" onclick="acymChartLineUpdate(this, \'hour\')">'.acym_translation('ACYM_BY_HOUR').'</p>
71 - </div>
72 - <div class="acym__chart__line__legend" id="'.$idLegend.'"></div>
73 - <canvas id="'.$idCanvas.'" height="400" width="400"></canvas>
74 - </div>';
82 + <script>
83 + <?php echo $ajax ? '' : 'document.addEventListener("DOMContentLoaded", function () {'; ?>
84 + const ctx = document.getElementById(<?php echo json_encode($idCanvas); ?>).getContext('2d');
75 85
76 - $return .= '<script>
77 - '.($ajax ? '' : 'document.addEventListener("DOMContentLoaded", function () {').'
78 - var ctx = document.getElementById("'.$idCanvas.'").getContext("2d");
79 -
80 - var gradientBlue = ctx.createLinearGradient(0, 0, 0, 400);
81 - gradientBlue.addColorStop(0, "rgba(128,182,244,0.5)");
82 - gradientBlue.addColorStop(0.5, "rgba(128,182,244,0.25)");
83 - gradientBlue.addColorStop(1, "rgba(128,182,244,0)");
84 -
85 - var gradientRed = ctx.createLinearGradient(0, 0, 0, 400);
86 - gradientRed.addColorStop(0., "rgba(255,82,89,0.5)");
87 - gradientRed.addColorStop(0.5, "rgba(255,82,89,0.25)");
88 - gradientRed.addColorStop(1, "rgba(255,82,89,0)");
89 -
90 - var config = {
91 - type: "line",
92 - data: {
93 - labels: ["'.acym_translation('ACYM_SENT').'", '.implode(',', $displayed).'],
94 - datasets: [{ //We place the open before, because there are less than the clicks
95 - label: "'.acym_translation('ACYM_CLICK').'",
96 - data: ["0", '.implode(',', $clickDisplayed).'],
97 - borderColor: "#00a4ff",
98 - fill: true,
99 - backgroundColor: gradientBlue,
100 - borderWidth: 3,
101 - pointBackgroundColor: "#ffffff",
102 - pointRadius: 5,
103 - },{
104 - label: "'.acym_translation('ACYM_OPEN').'",
105 - data: ["0", '.implode(',', $openDisplayed).'],
106 - borderColor: "#ff5259",
107 - fill: true,
108 - backgroundColor: gradientRed,
109 - borderWidth: 3,
110 - pointBackgroundColor: "#ffffff",
111 - pointRadius: 5,
112 - },]
113 - }, options: {
114 - responsive: true,
115 - legend: { //We make custom legends
116 - display: false,
117 - },
118 - tooltips: { //on hover the dot
119 - backgroundColor: "#fff",
120 - borderWidth: 2,
121 - borderColor: "#303e46",
122 - titleFontSize: 16,
123 - titleFontColor: "#303e46",
124 - bodyFontColor: "#303e46",
125 - bodyFontSize: 14,
126 - displayColors: false
127 - },
128 - maintainAspectRatio: false, //to fit in the div
129 - scales: {
130 - yAxes: [{
131 - gridLines: {
132 - display: false
133 - },
134 - ticks: { //label on the axesY
135 - display: true,
136 - fontColor: "#0a0a0a"
137 - }
138 - }],
139 - xAxes: [{
140 - gridLines: {
141 - display: false
142 - },
143 - ticks: { //label on the axesX
144 - display: true,
145 - fontSize: 14,
146 - fontColor: "#0a0a0a"
147 - }
148 - }],
149 - },
150 - legendCallback: function(chart) { //custom legends
151 - var text = [];
152 - for (var i = 0; i < chart.data.datasets.length; i++) {
153 - if (chart.data.datasets[i].label) {
154 - text.push(\'<div onclick="updateDataset(event, \'+ chart.legend.legendItems[i].datasetIndex + \', this)" class="acym_chart_line_labels"><div class="acym_chart_line_labels_circle" style="background-color: \' + chart.data.datasets[i].borderColor + \'"></div><span>\' + chart.data.datasets[i].label+\'</span></div>\');
86 + //Background color under the line
87 + const gradientBlue = ctx.createLinearGradient(0, 0, 0, 400);
88 + gradientBlue.addColorStop(0, 'rgba(128,182,244,0.5)');
89 + gradientBlue.addColorStop(0.5, 'rgba(128,182,244,0.25)');
90 + gradientBlue.addColorStop(1, 'rgba(128,182,244,0)');
155 91
156 - }
157 - }
158 - return text.join("");
92 + const gradientRed = ctx.createLinearGradient(0, 0, 0, 400);
93 + gradientRed.addColorStop(0., 'rgba(255,82,89,0.5)');
94 + gradientRed.addColorStop(0.5, 'rgba(255,82,89,0.25)');
95 + gradientRed.addColorStop(1, 'rgba(255,82,89,0)');
96 +
97 + const config = {
98 + type: 'line',
99 + data: {
100 + labels: <?php echo json_encode(array_merge([acym_translation('ACYM_SENT')], $displayed)); ?>,
101 + datasets: [
102 + {
103 + label: <?php echo json_encode(acym_translation('ACYM_CLICK')); ?>,
104 + data: <?php echo json_encode(array_merge(['0'], $clickDisplayed)); ?>,
105 + borderColor: '#00a4ff',
106 + fill: true,
107 + backgroundColor: gradientBlue,
108 + borderWidth: 3,
109 + pointBackgroundColor: '#ffffff',
110 + pointRadius: 5
111 + },
112 + {
113 + label: <?php echo json_encode(acym_translation('ACYM_OPEN')); ?>,
114 + data: <?php echo json_encode(array_merge(['0'], $openDisplayed)); ?>,
115 + borderColor: '#ff5259',
116 + fill: true,
117 + backgroundColor: gradientRed,
118 + borderWidth: 3,
119 + pointBackgroundColor: '#ffffff',
120 + pointRadius: 5
121 + }
122 + ]
123 + },
124 + options: {
125 + responsive: true,
126 + legend: {
127 + display: false
128 + },
129 + tooltips: {
130 + backgroundColor: '#fff',
131 + borderWidth: 2,
132 + borderColor: '#303e46',
133 + titleFontSize: 16,
134 + titleFontColor: '#303e46',
135 + bodyFontColor: '#303e46',
136 + bodyFontSize: 14,
137 + displayColors: false
138 + },
139 + maintainAspectRatio: false,
140 + scales: {
141 + yAxes: [
142 + {
143 + gridLines: {
144 + display: false
159 145 },
146 + ticks: {
147 + display: true,
148 + fontColor: '#0a0a0a'
149 + }
160 150 }
161 - };
162 - var chart = new Chart(ctx, config);
163 - document.getElementById("'.$idLegend.'").innerHTML = (chart.generateLegend());
164 - updateDataset = function(e, datasetIndex, element) { //hide and show dataset for the custom legends
165 - element = element.children[1];
166 - var index = datasetIndex;
167 - var ci = e.view.chart;
168 - var meta = ci.getDatasetMeta(index);
169 -
170 - meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
171 -
172 - if(element.style.textDecoration == "line-through"){
173 - element.style.textDecoration = "none";
174 - }else{
175 - element.style.textDecoration = "line-through";
151 + ],
152 + xAxes: [
153 + {
154 + gridLines: {
155 + display: false
156 + },
157 + ticks: {
158 + display: true,
159 + fontSize: 14,
160 + fontColor: '#0a0a0a'
161 + }
176 162 }
177 -
178 - ci.update();
179 - };
180 - acymChartLineUpdate = function(elem, by){
181 - document.getElementById("acym__time__linechart__input").value = by;
182 - var chartLineLabels = document.getElementsByClassName("acym_chart_line_labels");
183 - for (var i = 0; i < chartLineLabels.length; i++){
184 - chartLineLabels[i].getElementsByTagName("span")[0].style.textDecoration = "none";
185 - }
186 - if(by === "month"){
187 - var labels = ["'.acym_translation('ACYM_SENT').'", '.implode(',', $month).'];
188 - var dataOpen = ["0", '.implode(',', $openMonth).'];
189 - var dataClick = ["0", '.implode(',', $clickMonth).'];
190 - }else if(by == "day"){
191 - var labels = ["'.acym_translation('ACYM_SENT').'", '.implode(',', $day).'];
192 - var dataOpen = ["0", '.implode(',', $openDay).'];
193 - var dataClick = ["0", '.implode(',', $clickDay).'];
194 - }else if(by == "hour"){
195 - var labels = ["'.acym_translation('ACYM_SENT').'", '.implode(',', $hour).'];
196 - var dataOpen = ["0", '.implode(',', $openHour).'];
197 - var dataClick = ["0", '.implode(',', $clickHour).'];
163 + ]
164 + },
165 + legendCallback: function (chart) {
166 + const text = [];
167 + for (let i = 0 ; i < chart.data.datasets.length ; i++) {
168 + if (chart.data.datasets[i].label) {
169 + text.push(`<div onclick="updateDataset(event, ${chart.legend.legendItems[i].datasetIndex}, this)" class="acym_chart_line_labels">
170 + <div class="acym_chart_line_labels_circle" style="background-color: ${chart.data.datasets[i].borderColor}"></div>
171 + <span>${chart.data.datasets[i].label}</span>
172 + </div>`);
198 173 }
199 - chart.config.data.labels = labels,
200 - chart.config.data.datasets = [{ //We place the open before, because there are less than the clicks
201 - label: "'.acym_translation('ACYM_CLICK').'",
202 - data: dataClick,
203 - borderColor: "#00a4ff",
204 - fill: true,
205 - backgroundColor: gradientBlue,
206 - borderWidth: 3,
207 - pointBackgroundColor: "#ffffff",
208 - pointRadius: 5,
209 - },{
210 - label: "'.acym_translation('ACYM_OPEN').'",
211 - data: dataOpen,
212 - borderColor: "#ff5259",
213 - fill: true,
214 - backgroundColor: gradientRed,
215 - borderWidth: 3,
216 - pointBackgroundColor: "#ffffff",
217 - pointRadius: 5,
218 - }
219 - ];
220 - chart.update();
221 - var allChooseBy = document.getElementsByClassName("acym__chart__line__choose__by__one");
222 - for(var i = 0; i < allChooseBy.length;i++){
223 - allChooseBy[i].classList.remove("selected__choose_by");
224 - }
225 - elem.classList.add("selected__choose_by");
226 174 }
227 - document.querySelector(".selected__choose_by").click();
228 - '.($ajax ? '' : '});').'
229 - </script>';
175 + return text.join('');
176 + }
177 + }
178 + };
230 179
231 - return $return;
180 + const chart = new Chart(ctx, config);
181 + document.getElementById(<?php echo json_encode($idLegend); ?>).innerHTML = chart.generateLegend();
182 +
183 + updateDataset = function (e, datasetIndex, element) {
184 + element = element.children[1];
185 + const index = datasetIndex;
186 + const ci = e.view.chart;
187 + const meta = ci.getDatasetMeta(index);
188 +
189 + meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
190 +
191 + if (element.style.textDecoration === 'line-through') {
192 + element.style.textDecoration = 'none';
193 + } else {
194 + element.style.textDecoration = 'line-through';
195 + }
196 +
197 + ci.update();
198 + };
199 +
200 + acymChartLineUpdate = function (elem, by) {
201 + document.getElementById('acym__time__linechart__input').value = by;
202 + const chartLineLabels = document.getElementsByClassName('acym_chart_line_labels');
203 + for (let i = 0 ; i < chartLineLabels.length ; i++) {
204 + chartLineLabels[i].getElementsByTagName('span')[0].style.textDecoration = 'none';
205 + }
206 +
207 + let labels = [];
208 + let dataOpen = [];
209 + let dataClick = [];
210 +
211 + if (by === 'month') {
212 + labels = <?php echo json_encode(array_merge([acym_translation('ACYM_SENT')], $month)); ?>;
213 + dataOpen = <?php echo json_encode(array_merge(['0'], $openMonth)); ?>;
214 + dataClick = <?php echo json_encode(array_merge(['0'], $clickMonth)); ?>;
215 + } else if (by === 'day') {
216 + labels = <?php echo json_encode(array_merge([acym_translation('ACYM_SENT')], $day)); ?>;
217 + dataOpen = <?php echo json_encode(array_merge(['0'], $openDay)); ?>;
218 + dataClick = <?php echo json_encode(array_merge(['0'], $clickDay)); ?>;
219 + } else if (by === 'hour') {
220 + labels = <?php echo json_encode(array_merge([acym_translation('ACYM_SENT')], $hour)); ?>;
221 + dataOpen = <?php echo json_encode(array_merge(['0'], $openHour)); ?>;
222 + dataClick = <?php echo json_encode(array_merge(['0'], $clickHour)); ?>;
223 + }
224 +
225 + chart.config.data.labels = labels;
226 + chart.config.data.datasets = [
227 + {
228 + label: <?php echo json_encode(acym_translation('ACYM_CLICK')); ?>,
229 + data: dataClick,
230 + borderColor: '#00a4ff',
231 + fill: true,
232 + backgroundColor: gradientBlue,
233 + borderWidth: 3,
234 + pointBackgroundColor: '#ffffff',
235 + pointRadius: 5
236 + },
237 + {
238 + label: <?php echo json_encode(acym_translation('ACYM_OPEN')); ?>,
239 + data: dataOpen,
240 + borderColor: '#ff5259',
241 + fill: true,
242 + backgroundColor: gradientRed,
243 + borderWidth: 3,
244 + pointBackgroundColor: '#ffffff',
245 + pointRadius: 5
246 + }
247 + ];
248 + chart.update();
249 + const allChooseBy = document.getElementsByClassName('acym__chart__line__choose__by__one');
250 + for (let i = 0 ; i < allChooseBy.length ; i++) {
251 + allChooseBy[i].classList.remove('selected__choose_by');
252 + }
253 + elem.classList.add('selected__choose_by');
254 + };
255 +
256 + document.querySelector('.selected__choose_by').click();
257 + <?php echo $ajax ? '' : '});'; ?>
258 + </script>
259 + <?php
232 260 }
233 261
234 262 function acym_initializeChart(): void
235 263 {
@@ -240,17 +268,23 @@
240 268 $loaded = true;
241 269 }
242 270 }
243 271
244 -function acym_roundChart($percentage, string $type = '', string $class = '', string $topLabel = ''): string
272 +function acym_displayRoundChart($percentage, string $type = '', string $class = '', string $topLabel = '', string $centerText = ''): void
245 273 {
246 274 if (empty($percentage) && $percentage !== 0) {
247 - return '';
275 + return;
248 276 }
249 277
250 278 acym_initializeChart();
251 279
252 - $randNumber = rand(1000, 9000);
280 + // A total-based value can exceed 100% (e.g. anonymized opens/clicks): clamp the ring so it never overflows
281 + $gauge = max(0, min(100, (float)$percentage));
282 + if ($centerText === '') {
283 + $centerText = $percentage.'%';
284 + }
285 +
286 + $randNumber = acym_rand(1000, 9000);
253 287 $id = 'acy_round_chart_rand_id'.$randNumber;
254 288 $idCanvas = 'acy_canvas_rand_id'.$randNumber;
255 289
256 290 $green = '#3dea91';
@@ -291,86 +325,105 @@
291 325 $color = $defaultColor;
292 326 if (!$isFixColor) {
293 327 if ($percentage >= $valueHigh) {
294 328 $color = $isInverted ? $red : $green;
295 - } elseif ($percentage < $valueHigh && $percentage >= $valueLow) {
329 + } elseif ($percentage >= $valueLow) {
296 330 $color = $orange;
297 - } elseif ($percentage < $valueLow) {
331 + } else {
298 332 $color = $isInverted ? $green : $red;
299 333 }
300 334 }
335 + ?>
301 336
302 - $return = '<div class="'.$class.' acym__chart__doughnut text-center">
303 - <p class="text-center acym__chart__doughnut__container__top-label">'.$topLabel.'</p>
304 - <div class="acym__chart__doughnut__container" id="'.$id.'">
305 - <canvas id="'.$idCanvas.'" width="200" height="200"></canvas>
306 - </div>
307 - </div>';
308 - $return .= '<script>
309 - document.addEventListener("DOMContentLoaded", function () {
337 + <div class="<?php echo esc_attr($class); ?> acym__chart__doughnut text-center">
338 + <p class="text-center acym__chart__doughnut__container__top-label"><?php echo wp_kses($topLabel, ['span' => ['class' => true], 'label' => []]); ?></p>
339 + <div class="acym__chart__doughnut__container" id="<?php echo esc_attr($id); ?>">
340 + <canvas id="<?php echo esc_attr($idCanvas); ?>" width="200" height="200"></canvas>
341 + </div>
342 + </div>
343 +
344 + <script>
345 + // Override to add text in the middle of chart
346 + document.addEventListener('DOMContentLoaded', function () {
310 347 Chart.pluginService.register({
311 - beforeDraw: function(chart){
312 - if(chart.config.options.elements.center){
313 - var ctx = chart.chart.ctx;
314 -
315 - var centerConfig = chart.config.options.elements.center;
316 - var fontStyle = centerConfig.fontStyle || "Arial";
317 - var txt = centerConfig.text;
318 - var color = centerConfig.color || "#000";
319 - ctx.textAlign = "center";
320 - ctx.textBaseline = "middle";
321 - var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
322 - var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
323 - ctx.font = "15px " + fontStyle;
348 + beforeDraw: function (chart) {
349 + if (chart.config.options.elements.center) {
350 + const ctx = chart.chart.ctx;
351 +
352 + //Get options from the center object in options
353 + const centerConfig = chart.config.options.elements.center;
354 + const fontStyle = centerConfig.fontStyle || 'Arial';
355 + const txt = centerConfig.text;
356 + const color = centerConfig.color || '#000';
357 + //Set font settings to draw it correctly.
358 + ctx.textAlign = 'center';
359 + ctx.textBaseline = 'middle';
360 + const centerX = (
361 + (
362 + chart.chartArea.left + chart.chartArea.right
363 + ) / 2
364 + );
365 + const centerY = (
366 + (
367 + chart.chartArea.top + chart.chartArea.bottom
368 + ) / 2
369 + );
370 + ctx.font = '15px ' + fontStyle;
324 371 ctx.fillStyle = color;
325 -
372 +
373 + //Draw text in center
326 374 ctx.fillText(txt, centerX, centerY);
327 375 }
328 376 }
329 377 });
330 - var ctx = document.getElementById("'.$idCanvas.'").getContext("2d");
331 - var config = {
332 - type: "doughnut", data: {
333 - datasets: [{
334 - data: ['.$percentage.', (100 - '.$percentage.')], //Data of chart
335 - backgroundColor: ["'.$color.'", "#f1f1f1"], //Two color of chart
336 - borderWidth: 0 //no border
337 - }]
338 - }, options: {
378 +
379 + const ctx = document.getElementById(<?php echo json_encode($idCanvas); ?>).getContext('2d');
380 + const config = {
381 + type: 'doughnut',
382 + data: {
383 + datasets: [
384 + {
385 + data: <?php echo json_encode([$gauge, 100 - $gauge]); ?>,
386 + backgroundColor: <?php echo json_encode([$color, "#f1f1f1"]); ?>,
387 + borderWidth: 0
388 + }
389 + ]
390 + },
391 + options: {
339 392 responsive: true,
340 - legend: {
341 - display: false,
342 - },
393 + legend: {
394 + display: false
395 + },
343 396 elements: {
344 397 center: {
345 - text: "'.$percentage.'%", color: "#363636",
346 - fontStyle: "Poppins",
347 - sidePadding: 70
398 + text: <?php echo json_encode($centerText); ?>,
399 + color: '#363636',
400 + fontStyle: 'Poppins',
401 + sidePadding: 70
348 402 }
349 - },
350 - cutoutPercentage: 90, //thickness donut
403 + },
404 + cutoutPercentage: 90, // Thickness
351 405 tooltips: {
352 - enabled: false //disable the tooltips on hover
406 + enabled: false // Disable tooltips on hover
353 407 }
354 408 }
355 409 };
356 - var chart = new Chart(ctx, config);
357 - });
358 - </script>';
359 410
360 -
361 - return $return;
411 + new Chart(ctx, config);
412 + });
413 + </script>
414 + <?php
362 415 }
363 416
364 -function acym_pieChart(array $data = [], string $class = '', string $topLabel = '', bool $cap = true, bool $perList = false): string
417 +function acym_pieChart(array $data = [], string $class = '', string $topLabel = '', bool $cap = true, bool $perList = false): void
365 418 {
366 419 if (empty($data)) {
367 - return '';
420 + return;
368 421 }
369 422
370 423 acym_initializeChart();
371 424
372 - $randNumber = rand(1000, 9000);
425 + $randNumber = acym_rand(1000, 9000);
373 426 $id = 'acy_pie_chart_rand_id'.$randNumber;
374 427 $idCanvas = 'acy_canvas_rand_id'.$randNumber;
375 428 $idLegend = 'acy_legend_rand_id'.$randNumber;
376 429
@@ -376,11 +429,13 @@
376 429
377 430 $allLabelsArray = [];
378 431 $colors = [];
379 432
433 + // Sort values higher to lower
380 434 asort($data);
381 435 $data = array_reverse($data, true);
382 436
437 + // Move Others to the bottom
383 438 if (isset($data['ACYM_OTHER'])) {
384 439 $otherValue = $data['ACYM_OTHER'];
385 440 unset($data['ACYM_OTHER']);
386 441 $data['ACYM_OTHER'] = $otherValue;
@@ -419,89 +474,91 @@
419 474 $position++;
420 475 }
421 476 }
422 477
478 + // We capped the number of elements shown, add the remaining values as "Others" at the end
423 479 if ($othersValue > 0) {
424 480 $data['ACYM_OTHER'] = $othersValue;
425 481 $allLabelsArray[] = acym_translation('ACYM_OTHER');
426 482 $colors[] = acym_getChartColor($position);
427 483 }
484 + ?>
485 + <div class="<?php echo esc_attr($class); ?> acym__chart__pie grid-x">
486 + <p class="text-center acym__chart__pie__container__top-label cell medium-6"><?php echo wp_kses($topLabel, ['span' => ['class' => true], 'label' => []]); ?></p>
487 + <div class="acym__chart__pie__container grid-x cell" id="<?php echo esc_attr($id); ?>">
488 + <div class="acym__chart__pie__canvas_container cell medium-6">
489 + <canvas id="<?php echo esc_attr($idCanvas); ?>" width="200" height="200"></canvas>
490 + </div>
491 + <div class="acym__chart__pie__legend cell medium-6 padding-left-1" id="<?php echo esc_attr($idLegend); ?>"></div>
492 + </div>
493 + </div>
428 494
429 - $allNumbers = implode(',', $data);
430 - $allLabels = "'".implode("', '", $allLabelsArray)."'";
431 - $allColors = "'".implode("', '", $colors)."'";
432 -
433 - $return = '<div class="'.$class.' acym__chart__pie grid-x">
434 - <p class="text-center acym__chart__pie__container__top-label cell medium-6">'.$topLabel.'</p>
435 - <div class="acym__chart__pie__container grid-x cell" id="'.$id.'">
436 - <div class="acym__chart__pie__canvas_container cell medium-6">
437 - <canvas id="'.$idCanvas.'" width="200" height="200"></canvas>
438 - </div>
439 - <div class="acym__chart__pie__legend cell medium-6 padding-left-1" id="'.$idLegend.'"></div>
440 - </div>
441 - </div>';
442 -
443 - $return .= '<script>
444 - document.addEventListener("DOMContentLoaded", function () {
445 - const ctx = document.getElementById("'.$idCanvas.'").getContext("2d");
446 - const config = {
447 - type: "pie",
448 - data: {
449 - datasets: [{
450 - data: ['.$allNumbers.'],
451 - backgroundColor: ['.$allColors.'],
452 - }],
453 - labels: ['.$allLabels.']
454 - }, options: {
495 + <script>
496 + document.addEventListener('DOMContentLoaded', function () {
497 + const chart = new Chart(document.getElementById(<?php echo json_encode($idCanvas); ?>).getContext('2d'), {
498 + type: 'pie',
499 + data: {
500 + datasets: [
501 + {
502 + data: <?php echo json_encode(array_values($data)); ?>,
503 + backgroundColor: <?php echo json_encode($colors); ?>,
504 + }
505 + ],
506 + labels: <?php echo json_encode($allLabelsArray); ?>
507 + },
508 + options: {
455 509 responsive: true,
456 510 legend: {
457 - display: false,
458 - },
511 + display: false
512 + },
459 513 tooltips: {
460 - backgroundColor: "#fff",
514 + backgroundColor: '#fff',
461 515 borderWidth: 2,
462 - borderColor: "#303e46",
516 + borderColor: '#303e46',
463 517 titleFontSize: 16,
464 - titleFontColor: "#303e46",
465 - bodyFontColor: "#303e46",
466 - bodyFontSize: 14,
518 + titleFontColor: '#303e46',
519 + bodyFontColor: '#303e46',
520 + bodyFontSize: 14
467 521 },
468 - legendCallback: function(chart) {
522 + legendCallback: function (chart) {
469 523 const dataSets = chart.data.datasets;
470 524 const colors = dataSets[0].backgroundColor;
471 525 const numbers = dataSets[0].data;
472 526 const labels = chart.data.labels;
473 527 const text = [];
474 -
528 +
475 529 if (colors.length !== labels.length) {
476 - return "";
530 + return '';
477 531 }
478 -
479 - for (let i = 0; i < labels.length; i++) {
480 - text.push(\'<div class="acym_chart_pie_labels"><div class="acym_chart_pie_labels_circle" style="background-color: \' + colors[i] + \'"></div>\' + labels[i] + " (" + numbers[i] + ")" + \'</div>\');
532 +
533 + for (let i = 0 ; i < labels.length ; i++) {
534 + text.push(`
535 + <div class="acym_chart_pie_labels">
536 + <div class="acym_chart_pie_labels_circle" style="background-color: ${colors[i]}"></div>
537 + ${labels[i]} (${numbers[i]})
538 + </div>`);
481 539 }
482 -
483 - return text.join("");
484 - },
540 +
541 + return text.join('');
542 + }
485 543 }
486 - };
487 - const chart = new Chart(ctx, config);
488 - document.getElementById("'.$idLegend.'").innerHTML = (chart.generateLegend());
544 + });
545 +
546 + document.getElementById(<?php echo json_encode($idLegend); ?>).innerHTML = chart.generateLegend();
489 547 });
490 -</script>';
491 -
492 - return $return;
548 + </script>
549 + <?php
493 550 }
494 551
495 -function acym_barChart(array $data = [], string $topLabel = ''): string
552 +function acym_displayBarChart(array $data = [], string $topLabel = ''): void
496 553 {
497 554 if (empty($data)) {
498 - return '';
555 + return;
499 556 }
500 557
501 558 acym_initializeChart();
502 559
503 - $randNumber = rand(1000, 9000);
560 + $randNumber = acym_rand(1000, 9000);
504 561 $id = 'acy_pie_chart_rand_id'.$randNumber;
505 562 $idCanvas = 'acy_canvas_rand_id'.$randNumber;
506 563 $idLegend = 'acy_legend_rand_id'.$randNumber;
507 564
@@ -531,99 +588,103 @@
531 588 $data[acym_translation('ACYM_OTHER')] = $cappedValue;
532 589 $allLabelsArray[] = acym_translation('ACYM_OTHER');
533 590 $colors[] = acym_getChartColor($position);
534 591 }
592 + ?>
535 593
536 - $allNumbers = implode(',', $data);
537 - $allLabels = "'".implode("', '", $allLabelsArray)."'";
538 - $allColors = "'".implode("', '", $colors)."'";
594 + <div class="acym__chart__pie grid-x">
595 + <p class="text-center acym__chart__pie__container__top-label cell medium-6"><?php echo wp_kses($topLabel, ['span' => ['class' => true], 'label' => []]); ?></p>
596 + <div class="acym__chart__pie__container grid-x cell" id="<?php echo esc_attr($id); ?>">
597 + <div class="acym__chart__pie__canvas_container cell medium-6">
598 + <canvas id="<?php echo esc_attr($idCanvas); ?>" width="200" height="200"></canvas>
599 + </div>
600 + <div class="acym__chart__pie__legend cell medium-6 padding-left-1" id="<?php echo esc_attr($idLegend); ?>"></div>
601 + </div>
602 + </div>
539 603
540 - $return = '<div class="acym__chart__pie grid-x">
541 - <p class="text-center acym__chart__pie__container__top-label cell medium-6">'.$topLabel.'</p>
542 - <div class="acym__chart__pie__container grid-x cell" id="'.$id.'">
543 - <div class="acym__chart__pie__canvas_container cell medium-6">
544 - <canvas id="'.$idCanvas.'" width="200" height="200"></canvas>
545 - </div>
546 - <div class="acym__chart__pie__legend cell medium-6 padding-left-1" id="'.$idLegend.'"></div>
547 - </div>
548 - </div>';
549 - $return .= '<script>
550 -
551 - document.addEventListener("DOMContentLoaded", function () {
552 - var ctx = document.getElementById("'.$idCanvas.'").getContext("2d");
553 - var config = {
554 - type: "bar",
555 - data: {
556 - datasets: [{
557 - data: ['.$allNumbers.'], //Data of chart
558 - backgroundColor: ['.$allColors.'],
559 - }],
560 - labels: ['.$allLabels.']
561 - }, options: {
604 + <script>
605 + document.addEventListener('DOMContentLoaded', function () {
606 + const ctx = document.getElementById("<?php echo esc_attr($idCanvas); ?>").getContext('2d');
607 + const config = {
608 + type: 'bar',
609 + data: {
610 + datasets: [
611 + {
612 + data: <?php echo json_encode(array_values($data)); ?>,
613 + backgroundColor: <?php echo json_encode($colors); ?>,
614 + }
615 + ],
616 + labels: <?php echo json_encode($allLabelsArray); ?>
617 + },
618 + options: {
562 619 responsive: true,
563 620 legend: {
564 - display: false,
565 - },
621 + display: false
622 + },
566 623 tooltips: {
567 - backgroundColor: "#fff",
624 + backgroundColor: '#fff',
568 625 borderWidth: 2,
569 - borderColor: "#303e46",
626 + borderColor: '#303e46',
570 627 titleFontSize: 16,
571 - titleFontColor: "#303e46",
572 - bodyFontColor: "#303e46",
573 - bodyFontSize: 14,
628 + titleFontColor: '#303e46',
629 + bodyFontColor: '#303e46',
630 + bodyFontSize: 14
574 631 },
575 - legendCallback: function(chart) {
632 + legendCallback: function (chart) {
576 633 let dataSets = chart.data.datasets;
577 634 let colors = dataSets[0].backgroundColor;
578 635 let numbers = dataSets[0].data;
579 636 let labels = chart.data.labels;
580 637 let text = [];
581 -
638 +
582 639 if (colors.length !== labels.length) {
583 - return "";
640 + return '';
584 641 }
585 -
586 - for (let i = 0; i < labels.length; i++) {
587 - text.push(\'<div class="acym_chart_pie_labels"><div class="acym_chart_pie_labels_circle" style="background-color: \' + colors[i] + \'"></div>\' + labels[i] + " (" + numbers[i] + "%)" + \'</div>\');
642 +
643 + for (let i = 0 ; i < labels.length ; i++) {
644 + text.push(`<div class="acym_chart_pie_labels">
645 + <div class="acym_chart_pie_labels_circle" style="background-color: ${colors[i]}"></div>
646 + ${labels[i]} (${numbers[i]}%)
647 + </div>`);
588 648 }
589 -
590 - return text.join("");
649 +
650 + return text.join('');
591 651 },
592 -
652 +
593 653 scales: {
594 - xAxes: [
595 - {
596 - gridLines:{
597 - drawTicks:false
598 - },
599 - ticks: {
600 - display: false
654 + xAxes: [
655 + {
656 + gridLines: {
657 + drawTicks: false
658 + },
659 + ticks: {
660 + display: false
661 + }
601 662 }
602 - }
603 - ],
604 - yAxes: [
605 - {
606 - gridLines:{
607 - drawTicks:false,
608 - },
609 - ticks: {
610 - min: 0,
611 - max: 100,
612 - padding: 10
613 - },
614 - },
615 - ],
616 - },
663 + ],
664 + yAxes: [
665 + {
666 + gridLines: {
667 + drawTicks: false
668 + },
669 + ticks: {
670 + min: 0,
671 + max: 100,
672 + padding: 10
673 + }
674 + }
675 + ]
676 + }
617 677
618 678 }
619 679 };
620 - var chart = new Chart(ctx, config);
621 - document.getElementById("'.$idLegend.'").innerHTML = (chart.generateLegend());
680 + const chart = new Chart(ctx, config);
681 + document.getElementById(<?php echo json_encode($idLegend); ?>).innerHTML = (
682 + chart.generateLegend()
683 + );
622 684 });
623 -</script>';
624 -
625 - return $return;
685 + </script>
686 + <?php
626 687 }
627 688
628 689 function acym_getChartColor(int $position): string
629 690 {