From 9e31461073306702d002b6c7b3b61ce08c2364aa Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Wed, 20 Aug 2025 16:24:53 +0200 Subject: [PATCH] =?UTF-8?q?Dodaj=20metod=C4=99=20get=5Fmin=5Froas=20w=20kl?= =?UTF-8?q?asie=20Products=20oraz=20zaktualizuj=20szablon=20product=5Fhist?= =?UTF-8?q?ory.php,=20aby=20wy=C5=9Bwietla=C5=82=20lini=C4=99=20limitu=20R?= =?UTF-8?q?OAS=20na=20wykresie.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/ftp-kr.sync.cache.json | 4 +- autoload/controls/class.Products.php | 1 + autoload/factory/class.Products.php | 6 + templates/products/product_history.php | 148 ++++++++++++++++--------- 4 files changed, 106 insertions(+), 53 deletions(-) diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json index 91ca89a..855dd2b 100644 --- a/.vscode/ftp-kr.sync.cache.json +++ b/.vscode/ftp-kr.sync.cache.json @@ -73,8 +73,8 @@ }, "class.Products.php": { "type": "-", - "size": 4579, - "lmtime": 1754740016569, + "size": 4799, + "lmtime": 1754982600241, "modified": false }, "class.Users.php": { diff --git a/autoload/controls/class.Products.php b/autoload/controls/class.Products.php index c57872d..03fa008 100644 --- a/autoload/controls/class.Products.php +++ b/autoload/controls/class.Products.php @@ -150,6 +150,7 @@ class Products return \Tpl::view( 'products/product_history', [ 'client_id' => $client_id, 'product_id' => $product_id, + 'min_roas' => \factory\Products::get_min_roas( $product_id ) ] ); } diff --git a/autoload/factory/class.Products.php b/autoload/factory/class.Products.php index ece0a18..cc73b6b 100644 --- a/autoload/factory/class.Products.php +++ b/autoload/factory/class.Products.php @@ -2,6 +2,12 @@ namespace factory; class Products { + static public function get_min_roas( $product_id ) + { + global $mdb; + return $mdb -> get( 'products', 'min_roas', [ 'id' => $product_id ] ); + } + static public function get_client_bestseller_min_roas( $client_id ) { global $mdb; diff --git a/templates/products/product_history.php b/templates/products/product_history.php index 7a833ad..5f78ec6 100644 --- a/templates/products/product_history.php +++ b/templates/products/product_history.php @@ -127,62 +127,108 @@ }); }); - Highcharts.chart('container', { - title: { - text: ``, - }, - subtitle: { - text: ``, - }, - yAxis: { - title: { - text: '' - }, - }, - 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(); + const chart = Highcharts.chart('container', { + title: { text: `` }, + subtitle: { text: `` }, - if (day === 1 || this.isLast) { - return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`; - } else { - return null; - } + // (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' - } - } + 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 <<< + min_roas): ?> + (function() { + var limitVal = Number(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 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); + }); + }); + + })(); + }, error: function (jqXHR, textStatus, errorThrown) { console.error('Error AJAX:', textStatus, errorThrown);