PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.11.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.11.1
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
acymailing / back / Helpers / global / chart.php

chart.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.11.1, at back/Helpers/global/chart.php

646 lines 25.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 function acym_lineChart(array $dataMonth, array $dataDay, array $dataHour, bool $ajax = false): string
4 {
5 acym_initializeChart();
6
7 $month = [];
8 $openMonth = [];
9 $clickMonth = [];
10
11 foreach ($dataMonth as $key => $data) {
12 $month[] = '"'.$key.'"';
13 $openMonth[] = '"'.$data['open'].'"';
14 $clickMonth[] = '"'.$data['click'].'"';
15 }
16
17 $day = [];
18 $openDay = [];
19 $clickDay = [];
20
21 foreach ($dataDay as $key => $data) {
22 $day[] = '"'.$key.'"';
23 $openDay[] = '"'.$data['open'].'"';
24 $clickDay[] = '"'.$data['click'].'"';
25 }
26
27 $hour = [];
28 $openHour = [];
29 $clickHour = [];
30
31 foreach ($dataHour as $key => $data) {
32 $hour[] = '"'.$key.'"';
33 $openHour[] = '"'.$data['open'].'"';
34 $clickHour[] = '"'.$data['click'].'"';
35 }
36
37 $randNumber = rand(1000, 9000);
38 $idCanvas = 'acy_canvas_rand_id'.$randNumber;
39 $idLegend = 'acy_legend_rand_id'.$randNumber;
40 $return = '';
41
42 $nbDataDay = count($dataDay);
43 $nbDataHour = count($dataHour);
44 $selectedChartHour = "";
45 $selectedChartDay = "";
46 $selectedChartMonth = "";
47
48 if ($nbDataHour < 49) {
49 $selectedChartHour = "selected__choose_by";
50 $displayed = $hour;
51 $clickDisplayed = $clickHour;
52 $openDisplayed = $openHour;
53 } elseif ($nbDataDay < 63) {
54 $selectedChartDay = "selected__choose_by";
55 $displayed = $day;
56 $clickDisplayed = $clickDay;
57 $openDisplayed = $openDay;
58 } else {
59 $selectedChartMonth = "selected__choose_by";
60 $displayed = $month;
61 $clickDisplayed = $clickMonth;
62 $openDisplayed = $openMonth;
63 }
64
65
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>';
75
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>\');
155
156 }
157 }
158 return text.join("");
159 },
160 }
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";
176 }
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).'];
198 }
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 }
227 document.querySelector(".selected__choose_by").click();
228 '.($ajax ? '' : '});').'
229 </script>';
230
231 return $return;
232 }
233
234 function acym_initializeChart(): void
235 {
236 static $loaded = false;
237
238 if (!$loaded) {
239 acym_addScript(false, ACYM_JS.'libraries/chart.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'chart.min.js'), ['defer' => false, 'needTagScript' => true]);
240 $loaded = true;
241 }
242 }
243
244 function acym_roundChart($percentage, string $type = '', string $class = '', string $topLabel = ''): string
245 {
246 if (empty($percentage) && $percentage !== 0) {
247 return '';
248 }
249
250 acym_initializeChart();
251
252 $randNumber = rand(1000, 9000);
253 $id = 'acy_round_chart_rand_id'.$randNumber;
254 $idCanvas = 'acy_canvas_rand_id'.$randNumber;
255
256 $green = '#3dea91';
257 $red = '#ff5259';
258 $orange = '#ffab15';
259 $defaultColor = '#00a4ff';
260
261 $isFixColor = false;
262 $isInverted = false;
263
264 switch ($type) {
265 case 'click':
266 $valueHigh = 5;
267 $valueLow = 1;
268 break;
269 case 'open':
270 $valueHigh = 30;
271 $valueLow = 18;
272 break;
273 case 'delivery':
274 $valueHigh = 90;
275 $valueLow = 70;
276 break;
277 case 'fail':
278 $valueHigh = 30;
279 $valueLow = 10;
280 $isInverted = true;
281 break;
282 case 'unsubscribe':
283 $valueHigh = 10;
284 $valueLow = 1;
285 $isInverted = true;
286 break;
287 default:
288 $isFixColor = true;
289 }
290
291 $color = $defaultColor;
292 if (!$isFixColor) {
293 if ($percentage >= $valueHigh) {
294 $color = $isInverted ? $red : $green;
295 } elseif ($percentage < $valueHigh && $percentage >= $valueLow) {
296 $color = $orange;
297 } elseif ($percentage < $valueLow) {
298 $color = $isInverted ? $green : $red;
299 }
300 }
301
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 () {
310 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;
324 ctx.fillStyle = color;
325
326 ctx.fillText(txt, centerX, centerY);
327 }
328 }
329 });
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: {
339 responsive: true,
340 legend: {
341 display: false,
342 },
343 elements: {
344 center: {
345 text: "'.$percentage.'%", color: "#363636",
346 fontStyle: "Poppins",
347 sidePadding: 70
348 }
349 },
350 cutoutPercentage: 90, //thickness donut
351 tooltips: {
352 enabled: false //disable the tooltips on hover
353 }
354 }
355 };
356 var chart = new Chart(ctx, config);
357 });
358 </script>';
359
360
361 return $return;
362 }
363
364 function acym_pieChart(array $data = [], string $class = '', string $topLabel = '', bool $cap = true, bool $perList = false): string
365 {
366 if (empty($data)) {
367 return '';
368 }
369
370 acym_initializeChart();
371
372 $randNumber = rand(1000, 9000);
373 $id = 'acy_pie_chart_rand_id'.$randNumber;
374 $idCanvas = 'acy_canvas_rand_id'.$randNumber;
375 $idLegend = 'acy_legend_rand_id'.$randNumber;
376
377 $allLabelsArray = [];
378 $colors = [];
379
380 asort($data);
381 $data = array_reverse($data, true);
382
383 if (isset($data['ACYM_OTHER'])) {
384 $otherValue = $data['ACYM_OTHER'];
385 unset($data['ACYM_OTHER']);
386 $data['ACYM_OTHER'] = $otherValue;
387 }
388
389 $position = 0;
390 $othersValue = 0;
391 $nbOthers = 0;
392 if ($perList) {
393 foreach ($data as $itemId => $item) {
394 if ($position > 9 && $cap) {
395 $othersValue += (float)$item['value'];
396 unset($data[$itemId]);
397 $nbOthers++;
398 continue;
399 }
400 $data[$itemId] = (float)$item['value'];
401 $allLabelsArray[] = $item['label'];
402 $colors[] = $item['color'];
403 $position++;
404 }
405
406 if ($othersValue > 0) {
407 $othersValue = $othersValue / $nbOthers;
408 }
409 } else {
410 foreach ($data as $label => $number) {
411 if ($position > 9 && $cap) {
412 $othersValue += (float)$number;
413 unset($data[$label]);
414 continue;
415 }
416 $data[$label] = (float)$number;
417 $allLabelsArray[] = acym_translation($label);
418 $colors[] = acym_getChartColor($position);
419 $position++;
420 }
421 }
422
423 if ($othersValue > 0) {
424 $data['ACYM_OTHER'] = $othersValue;
425 $allLabelsArray[] = acym_translation('ACYM_OTHER');
426 $colors[] = acym_getChartColor($position);
427 }
428
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: {
455 responsive: true,
456 legend: {
457 display: false,
458 },
459 tooltips: {
460 backgroundColor: "#fff",
461 borderWidth: 2,
462 borderColor: "#303e46",
463 titleFontSize: 16,
464 titleFontColor: "#303e46",
465 bodyFontColor: "#303e46",
466 bodyFontSize: 14,
467 },
468 legendCallback: function(chart) {
469 const dataSets = chart.data.datasets;
470 const colors = dataSets[0].backgroundColor;
471 const numbers = dataSets[0].data;
472 const labels = chart.data.labels;
473 const text = [];
474
475 if (colors.length !== labels.length) {
476 return "";
477 }
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>\');
481 }
482
483 return text.join("");
484 },
485 }
486 };
487 const chart = new Chart(ctx, config);
488 document.getElementById("'.$idLegend.'").innerHTML = (chart.generateLegend());
489 });
490 </script>';
491
492 return $return;
493 }
494
495 function acym_barChart(array $data = [], string $topLabel = ''): string
496 {
497 if (empty($data)) {
498 return '';
499 }
500
501 acym_initializeChart();
502
503 $randNumber = rand(1000, 9000);
504 $id = 'acy_pie_chart_rand_id'.$randNumber;
505 $idCanvas = 'acy_canvas_rand_id'.$randNumber;
506 $idLegend = 'acy_legend_rand_id'.$randNumber;
507
508 $allLabelsArray = [];
509 $colors = [];
510
511 asort($data);
512 $data = array_reverse($data, true);
513 $position = 0;
514 $cappedValue = 0;
515 $nbOther = 0;
516 foreach ($data as $itemId => $item) {
517 if ($position > 9) {
518 $cappedValue += (float)$item['value'];
519 unset($data[$itemId]);
520 $nbOther++;
521 continue;
522 }
523 $data[$itemId] = (float)$item['value'];
524 $allLabelsArray[] = $item['label'];
525 $colors[] = $item['color'];
526 $position++;
527 }
528
529 if ($cappedValue > 0) {
530 $cappedValue = $cappedValue / $nbOther;
531 $data[acym_translation('ACYM_OTHER')] = $cappedValue;
532 $allLabelsArray[] = acym_translation('ACYM_OTHER');
533 $colors[] = acym_getChartColor($position);
534 }
535
536 $allNumbers = implode(',', $data);
537 $allLabels = "'".implode("', '", $allLabelsArray)."'";
538 $allColors = "'".implode("', '", $colors)."'";
539
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: {
562 responsive: true,
563 legend: {
564 display: false,
565 },
566 tooltips: {
567 backgroundColor: "#fff",
568 borderWidth: 2,
569 borderColor: "#303e46",
570 titleFontSize: 16,
571 titleFontColor: "#303e46",
572 bodyFontColor: "#303e46",
573 bodyFontSize: 14,
574 },
575 legendCallback: function(chart) {
576 let dataSets = chart.data.datasets;
577 let colors = dataSets[0].backgroundColor;
578 let numbers = dataSets[0].data;
579 let labels = chart.data.labels;
580 let text = [];
581
582 if (colors.length !== labels.length) {
583 return "";
584 }
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>\');
588 }
589
590 return text.join("");
591 },
592
593 scales: {
594 xAxes: [
595 {
596 gridLines:{
597 drawTicks:false
598 },
599 ticks: {
600 display: false
601 }
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 },
617
618 }
619 };
620 var chart = new Chart(ctx, config);
621 document.getElementById("'.$idLegend.'").innerHTML = (chart.generateLegend());
622 });
623 </script>';
624
625 return $return;
626 }
627
628 function acym_getChartColor(int $position): string
629 {
630 $colors = [
631 '#845EC2',
632 '#D65DB1',
633 '#FF6F91',
634 '#FF9671',
635 '#FFC75F',
636 '#F9F871',
637 '#8BE884',
638 '#00CFA9',
639 '#00AFC6',
640 '#008AC9',
641 '#2261AC',
642 ];
643
644 return $colors[$position % 11];
645 }
646