feat: объединить все температурные метрики (temp_*) в один график с разными цветами, вернуть сетевые графики
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
dbd71e3485
commit
ce577c5d51
|
|
@ -123,7 +123,7 @@
|
|||
|
||||
<div class="row">
|
||||
{% for metricName, metricData in metrics %}
|
||||
{% if metricName!="top_cpu_proc" and metricName!="top_ram_proc" and metricName!="disk_used" and not (metricName starts with "disk_used_") and not (metricName starts with "disk_total_gb_") and metricName!="ram_total_gb" and not (metricName starts with "net_in_") and not (metricName starts with "net_out_") and metricName!="network_rx" and metricName!="network_tx" %}
|
||||
{% if metricName!="top_cpu_proc" and metricName!="top_ram_proc" and metricName!="disk_used" and not (metricName starts with "disk_used_") and not (metricName starts with "disk_total_gb_") and metricName!="ram_total_gb" and not (metricName starts with "net_in_") and not (metricName starts with "net_out_") and metricName!="network_rx" and metricName!="network_tx" and not (metricName starts with "temp_") %}
|
||||
<div class="col-12 mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
|
|
@ -160,10 +160,36 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- Температуры -->
|
||||
{% set has_temps = false %}
|
||||
{% for m in metrics %}{% if m starts with 'temp_' %}{% set has_temps = true %}{% endif %}{% endfor %}
|
||||
{% if has_temps %}
|
||||
<!-- Графики сетевых интерфейсов -->
|
||||
{% set net_interfaces = [] %}
|
||||
{% for metricName in metrics|keys %}
|
||||
{% if metricName starts with 'net_in_' %}
|
||||
{% set iface = metricName|replace({'net_in_': ''}) %}
|
||||
{% set net_interfaces = net_interfaces|merge([iface]) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for iface in net_interfaces %}
|
||||
{% if metrics['net_in_' ~ iface] is defined and metrics['net_out_' ~ iface] is defined %}
|
||||
<div class="row">
|
||||
<div class="col-12 mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h6 class="mb-0"><i class="fas fa-network-wired"></i> Сеть: {{ iface }}</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="chart-net-{{ iface }}" width="100%" height="200"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Температуры: один общий график -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
|
|
@ -171,12 +197,11 @@
|
|||
<h6 class="mb-0"><i class="fas fa-thermometer-half"></i> Температуры</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="chart-temperatures" width="100%" height="200"></canvas>
|
||||
<canvas id="chart-temperatures" width="100%" height="300"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Диски: Doughnut графики -->
|
||||
<div class="row mb-3">
|
||||
|
|
@ -552,7 +577,7 @@ var diskTotalGB = {
|
|||
|
||||
// Графики метрик
|
||||
{% for metricName, metricData in metrics %}
|
||||
{% if metricName!="top_cpu_proc" and metricName!="top_ram_proc" and metricName!="disk_used" and not (metricName starts with "disk_used_") and not (metricName starts with "disk_total_gb_") and metricName!="ram_total_gb" and not (metricName starts with "net_in_") and not (metricName starts with "net_out_") and metricName!="network_rx" and metricName!="network_tx" %}
|
||||
{% if metricName!="top_cpu_proc" and metricName!="top_ram_proc" and metricName!="disk_used" and not (metricName starts with "disk_used_") and not (metricName starts with "disk_total_gb_") and metricName!="ram_total_gb" and not (metricName starts with "net_in_") and not (metricName starts with "net_out_") and metricName!="network_rx" and metricName!="network_tx" and not (metricName starts with "temp_") %}
|
||||
const ctx{{ metricName|replace({'-': '_', '.': '_'}) }} = document.getElementById('chart-{{ metricName }}').getContext('2d');
|
||||
|
||||
// Подготовка данных для графика
|
||||
|
|
@ -726,7 +751,7 @@ chart{{ metricName|replace({'-': '_', '.': '_'}) }}.canvas.addEventListener('mou
|
|||
// Глобальный обработчик для скрытия тултипов при уходе курсора за пределы canvas
|
||||
document.addEventListener('mousemove', function(e) {
|
||||
{% for metricName, metricData in metrics %}
|
||||
{% if metricName!="top_cpu_proc" and metricName!="top_ram_proc" and metricName!="disk_used" and not (metricName starts with "disk_used_") and not (metricName starts with "disk_total_gb_") and metricName!="ram_total_gb" and not (metricName starts with "net_in_") and not (metricName starts with "net_out_") and metricName!="network_rx" and metricName!="network_tx" %}
|
||||
{% if metricName!="top_cpu_proc" and metricName!="top_ram_proc" and metricName!="disk_used" and not (metricName starts with "disk_used_") and not (metricName starts with "disk_total_gb_") and metricName!="ram_total_gb" and not (metricName starts with "net_in_") and not (metricName starts with "net_out_") and metricName!="network_rx" and metricName!="network_tx" and not (metricName starts with "temp_") %}
|
||||
(function() {
|
||||
var canvas = chart{{ metricName|replace({'-': '_', '.': '_'}) }}.canvas;
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
|
|
@ -748,40 +773,61 @@ document.addEventListener('mousemove', function(e) {
|
|||
|
||||
|
||||
|
||||
// График температур
|
||||
{% set temp_metrics = [] %}
|
||||
{% for m in metrics %}{% if m starts with 'temp_' %}{% set temp_metrics = temp_metrics|merge([m]) %}{% endif %}{% endfor %}
|
||||
{% if temp_metrics %}
|
||||
// Графики сетевых интерфейсов (две линии: In зелёная, Out красная)
|
||||
{% set net_interfaces = [] %}
|
||||
{% for metricName in metrics|keys %}
|
||||
{% if metricName starts with 'net_in_' %}
|
||||
{% set net_interfaces = net_interfaces|merge([metricName|replace({'net_in_': ''})]) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for iface in net_interfaces %}
|
||||
{% if metrics['net_in_' ~ iface] is defined and metrics['net_out_' ~ iface] is defined %}
|
||||
(function() {
|
||||
var ctx = document.getElementById('chart-temperatures');
|
||||
var ctx = document.getElementById('chart-net-{{ iface }}');
|
||||
if (!ctx) return;
|
||||
|
||||
var labels = [];
|
||||
{% if metrics[temp_metrics[0]] is defined %}
|
||||
{% for p in metrics[temp_metrics[0]]|slice(-100) %}
|
||||
labels.push('{{ p.time_bucket|default(p.created_at)|date("d.m H:i") }}');
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
var inData = [];
|
||||
var outData = [];
|
||||
|
||||
var datasets = [];
|
||||
{% for m in temp_metrics %}
|
||||
var data_{{ m }} = {
|
||||
label: '{{ m|replace({'temp_': '', '_': ' '})|title }}',
|
||||
data: [],
|
||||
fill: false,
|
||||
tension: 0.1,
|
||||
pointRadius: 1,
|
||||
borderWidth: 1
|
||||
};
|
||||
{% for p in metrics[m]|slice(-100) %}
|
||||
data_{{ m }}.data.push({{ p.value }});
|
||||
{% endfor %}
|
||||
datasets.push(data_{{ m }});
|
||||
{% endfor %}
|
||||
{% for m in metrics['net_in_' ~ iface]|slice(0, 500)|reverse %}
|
||||
labels.push('{{ m.created_at|date("d.m H:i") }}');
|
||||
inData.push({{ m.value }});
|
||||
{% endfor %}
|
||||
|
||||
{% set outMetrics = metrics['net_out_' ~ iface]|slice(0, 500)|reverse %}
|
||||
{% for m in outMetrics %}
|
||||
outData.push({{ m.value }});
|
||||
{% endfor %}
|
||||
|
||||
new Chart(ctx.getContext('2d'), {
|
||||
type: 'line',
|
||||
data: { labels: labels, datasets: datasets },
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Входящий (In)',
|
||||
data: inData,
|
||||
borderColor: 'rgba(25, 135, 84, 1)',
|
||||
backgroundColor: 'rgba(25, 135, 84, 0.1)',
|
||||
fill: true,
|
||||
tension: 0.1,
|
||||
pointRadius: 0,
|
||||
borderWidth: 1.5
|
||||
},
|
||||
{
|
||||
label: 'Исходящий (Out)',
|
||||
data: outData,
|
||||
borderColor: 'rgba(220, 53, 69, 1)',
|
||||
backgroundColor: 'rgba(220, 53, 69, 0.1)',
|
||||
fill: true,
|
||||
tension: 0.1,
|
||||
pointRadius: 0,
|
||||
borderWidth: 1.5
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
|
|
@ -789,13 +835,97 @@ document.addEventListener('mousemove', function(e) {
|
|||
plugins: {
|
||||
legend: { display: true, position: 'top' },
|
||||
tooltip: { enabled: true, mode: 'index', intersect: false },
|
||||
zoom: { zoom: { wheel: { enabled: true }, pinch: { enabled: true }, mode: 'x' }, pan: { enabled: true, mode: 'x' } }
|
||||
zoom: {
|
||||
zoom: { wheel: { enabled: true }, pinch: { enabled: true }, mode: 'x' },
|
||||
pan: { enabled: true, mode: 'x' }
|
||||
}
|
||||
},
|
||||
scales: { y: { beginAtZero: false, ticks: { callback: v => v + '°C' } } }
|
||||
scales: {
|
||||
y: { beginAtZero: true, ticks: { callback: function(v) { return v + '%'; } } }
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
// График температур — ВСЕ temp_* на одном графике
|
||||
(function() {
|
||||
var ctx = document.getElementById('chart-temperatures');
|
||||
if (!ctx) return;
|
||||
|
||||
var tempColors = [
|
||||
{ border: 'rgba(255, 99, 132, 1)', bg: 'rgba(255, 99, 132, 0.1)' },
|
||||
{ border: 'rgba(75, 192, 192, 1)', bg: 'rgba(75, 192, 192, 0.1)' },
|
||||
{ border: 'rgba(255, 159, 64, 1)', bg: 'rgba(255, 159, 64, 0.1)' },
|
||||
{ border: 'rgba(255, 205, 86, 1)', bg: 'rgba(255, 205, 86, 0.1)' },
|
||||
{ border: 'rgba(201, 203, 207, 1)', bg: 'rgba(201, 203, 207, 0.1)' },
|
||||
{ border: 'rgba(54, 162, 235, 1)', bg: 'rgba(54, 162, 235, 0.1)' },
|
||||
{ border: 'rgba(153, 102, 255, 1)', bg: 'rgba(153, 102, 255, 0.1)' },
|
||||
{ border: 'rgba(255, 99, 255, 1)', bg: 'rgba(255, 99, 255, 0.1)' },
|
||||
{ border: 'rgba(100, 200, 100, 1)', bg: 'rgba(100, 200, 100, 0.1)' },
|
||||
{ border: 'rgba(200, 150, 50, 1)', bg: 'rgba(200, 150, 50, 0.1)' }
|
||||
];
|
||||
|
||||
var labels = [];
|
||||
var labelsFilled = false;
|
||||
var datasets = [];
|
||||
var colorIdx = 0;
|
||||
|
||||
{% for mn, md in metrics %}
|
||||
{% if mn starts with 'temp_' %}
|
||||
if (!labelsFilled) {
|
||||
{% for p in md|slice(-1000) %}
|
||||
labels.push('{{ p.time_bucket|default(p.created_at)|date("d.m H:i") }}');
|
||||
{% endfor %}
|
||||
labelsFilled = true;
|
||||
}
|
||||
|
||||
(function() {
|
||||
var data = [];
|
||||
{% for p in md|slice(-1000) %}
|
||||
data.push({{ p.value }});
|
||||
{% endfor %}
|
||||
|
||||
var color = tempColors[colorIdx % tempColors.length];
|
||||
colorIdx++;
|
||||
|
||||
datasets.push({
|
||||
label: '{{ mn|replace({'temp_': '', '_': ' '})|title }}',
|
||||
data: data,
|
||||
borderColor: color.border,
|
||||
backgroundColor: color.bg,
|
||||
fill: false,
|
||||
tension: 0.1,
|
||||
pointRadius: 1,
|
||||
borderWidth: 2
|
||||
});
|
||||
})();
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
var chart = new Chart(ctx.getContext('2d'), {
|
||||
type: 'line',
|
||||
data: { labels: labels, datasets: datasets },
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
interaction: { mode: 'index', intersect: false },
|
||||
plugins: {
|
||||
legend: { display: true, position: 'top', labels: { boxWidth: 12, font: { size: 11 } } },
|
||||
tooltip: { enabled: true, mode: 'index', intersect: false },
|
||||
zoom: {
|
||||
zoom: { wheel: { enabled: true }, pinch: { enabled: true }, mode: 'x' },
|
||||
pan: { enabled: true, mode: 'x' }
|
||||
}
|
||||
},
|
||||
scales: { y: { beginAtZero: false, ticks: { callback: function(v) { return v + '°C'; } } } }
|
||||
}
|
||||
});
|
||||
|
||||
window.chartTemperatures = chart;
|
||||
})();
|
||||
|
||||
// Doughnut графики для разделов дисков
|
||||
{% for metricName, metricData in metrics %}
|
||||
|
|
@ -842,12 +972,15 @@ document.addEventListener('mousemove', function(e) {
|
|||
// Сбросить зум на всех графиках
|
||||
function resetAllZoom() {
|
||||
{% for metricName, metricData in metrics %}
|
||||
{% if metricName!="top_cpu_proc" and metricName!="top_ram_proc" and metricName!="disk_used" and not (metricName starts with "disk_used_") and not (metricName starts with "disk_total_gb_") and metricName!="ram_total_gb" and not (metricName starts with "net_in_") and not (metricName starts with "net_out_") and metricName!="network_rx" and metricName!="network_tx" %}
|
||||
{% if metricName!="top_cpu_proc" and metricName!="top_ram_proc" and metricName!="disk_used" and not (metricName starts with "disk_used_") and not (metricName starts with "disk_total_gb_") and metricName!="ram_total_gb" and not (metricName starts with "net_in_") and not (metricName starts with "net_out_") and metricName!="network_rx" and metricName!="network_tx" and not (metricName starts with "temp_") %}
|
||||
if (typeof chart{{ metricName|replace({'-': '_', '.': '_'}) }} !== 'undefined') {
|
||||
chart{{ metricName|replace({'-': '_', '.': '_'}) }}.resetZoom();
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
if (typeof window.chartTemperatures !== 'undefined') {
|
||||
window.chartTemperatures.resetZoom();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue