Files
adsPRO/templates/products/product_history.php

238 lines
6.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div class="admin-form theme-primary">
<div class="panel heading-border panel-primary">
<div class="panel-body">
<figure class="highcharts-figure">
<div id="container"></div>
</figure>
</div>
</div>
</div>
<div class="admin-form theme-primary">
<div class="panel heading-border panel-primary">
<div class="panel-body">
<table class="table" id="products">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Wyświetlenia</th>
<th scope="col">Kliknięcia</th>
<th scope="col">CTR</th>
<th scope="col">Koszt</th>
<th scope="col">Konwersje</th>
<th scope="col">Wartość konwersji</th>
<th scope="col">ROAS</th>
<th scope="col">Data</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript">
$( function() {
var client_id = <?= $this -> client_id;?>;
var product_id = <?= $this -> product_id;?>;
table = $( '#products' ).DataTable();
table.destroy();
new DataTable( '#products', {
ajax: {
type: 'POST',
url: '/products/get_product_history_table/client_id=' + client_id + '&product_id=' + product_id,
},
processing: true,
serverSide: true,
searching: false,
columns: [{
width: '100px',
orderable: false
},
{
width: '100px',
name: 'impressions'
},
{
width: '100px',
name: 'clicks'
},
{
width: '100px',
name: 'ctr',
className: "dt-type-numeric"
},
{
width: '100px',
name: 'cost',
className: "dt-type-numeric"
},
{
width: '100px',
name: 'conversions'
},
{
width: '175px',
name: 'conversions_value',
className: "dt-type-numeric"
},
{
width: '100px',
name: 'roas',
className: "dt-type-numeric",
orderable: false
},
{
width: '100px',
name: 'date_add'
},
],
order: [
[ 0, false],
[ 8, 'desc']
]
});
$.ajax({
url: '/products/get_product_history_table_chart/',
method: 'POST',
data: {
client_id: client_id,
product_id: product_id,
},
success: function(response) {
const parsedData = JSON.parse(response);
let plotLines = [];
parsedData.comments.forEach(function(comment) {
plotLines.push({
color: '#333333',
width: 1,
value: parsedData.dates.indexOf(comment.date_add.split(' ')[0]),
dashStyle: 'Solid',
label: {
text: comment.comment,
align: 'left',
style: {
color: '#333333',
fontSize: '14px'
}
},
zIndex: 5
});
});
const chart = Highcharts.chart('container', {
title: { text: `` },
subtitle: { text: `` },
// (możesz zostawić lub usunąć warunkowy blok yAxis z PHP — ten kod zadziała niezależnie)
xAxis: {
categories: parsedData.dates,
labels: {
style: { fontSize: '14px' },
formatter: function() {
var date = new Date(Date.parse(this.value));
var day = date.getDate();
var month = date.getMonth() + 1;
var year = date.getFullYear();
if (day === 1 || this.isLast) {
return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`;
} else {
return null;
}
}
},
plotLines: plotLines
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
itemStyle: { fontSize: '14px' }
},
plotOptions: {
series: { label: { connectorAllowed: false }, pointStart: 0 }
},
series: parsedData.chart_data,
tooltip: { style: { fontSize: '14px' } }
});
// >>> DODAJ TO PO UTWORZENIU WYKRESU <<<
<?php if ($this->min_roas): ?>
(function() {
var limitVal = Number(<?= json_encode($this->min_roas) ?>);
var roasSeries = chart.series.find(function(s) {
return (s.name || '').toLowerCase() === 'roas';
});
var targetAxis = roasSeries ? roasSeries.yAxis : chart.yAxis[0];
// dodanie linii
targetAxis.addPlotLine({
id: 'min-roas-line',
color: 'red',
width: 2,
value: limitVal,
dashStyle: 'Dash',
zIndex: 5,
label: {
text: 'Limit <?= htmlspecialchars((string)$this->min_roas, ENT_QUOTES) ?>',
align: 'right',
style: { color: 'red', fontSize: '14px' }
}
});
function adjustAxisToIncludeValue(axis, val) {
var e = axis.getExtremes();
if (e.dataMin == null || e.dataMax == null) return;
var min = Math.min(e.dataMin, val);
var max = Math.max(e.dataMax, val);
var span = (max - min) || 1;
var pad = span * 0.05;
var newMin = min - pad;
var newMax = max + pad;
// uniknij niepotrzebnych setExtremes
if (newMin !== e.min || newMax !== e.max) {
axis.setExtremes(newMin, newMax); // domyślnie robi redraw
}
}
// 1) po załadowaniu wykresu (jeśli już załadowany od razu)
if (chart.hasLoaded) {
adjustAxisToIncludeValue(targetAxis, limitVal);
} else {
Highcharts.addEvent(chart, 'load', function () {
adjustAxisToIncludeValue(targetAxis, limitVal);
});
}
// 2) przy show/hide serii (klik w legendzie)
chart.series.forEach(function (s) {
Highcharts.addEvent(s, 'show', function () {
adjustAxisToIncludeValue(targetAxis, limitVal);
});
Highcharts.addEvent(s, 'hide', function () {
adjustAxisToIncludeValue(targetAxis, limitVal);
});
});
})();
<?php endif; ?>
},
error: function (jqXHR, textStatus, errorThrown) {
console.error('Error AJAX:', textStatus, errorThrown);
}
})
})
</script>