Add dynamic metric loading on chart zoom
- Add onZoomComplete callback to charts - When zoomed to < 100 points, load detailed data from API - Add loadDetailedMetrics function per chart - API returns aggregated data (max 500 points) for zoomed range - Improves performance while preserving detail on zoom
This commit is contained in:
parent
66d4d021ba
commit
36ace1e9d2
|
|
@ -804,7 +804,39 @@ const chart{{ metricName|replace({'-': '_', '.': '_'}) }} = new Chart(ctx{{ metr
|
||||||
wheel: {
|
wheel: {
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
mode: 'x'
|
mode: 'x',
|
||||||
|
onZoomComplete: function(chart) {
|
||||||
|
// Сохраняем оригинальный диапазон если ещё не сохраняли
|
||||||
|
if (!chart._originalMinIndex && !chart._originalMaxIndex) {
|
||||||
|
chart._originalMinIndex = 0;
|
||||||
|
chart._originalMaxIndex = chart.data.labels.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получаем новый диапазон после зума
|
||||||
|
var scale = chart.scales.x;
|
||||||
|
var newMinIndex = Math.floor(scale.min);
|
||||||
|
var newMaxIndex = Math.ceil(scale.max);
|
||||||
|
|
||||||
|
// Ограничиваем индексы
|
||||||
|
newMinIndex = Math.max(0, newMinIndex);
|
||||||
|
newMaxIndex = Math.min(chart.data.labels.length - 1, newMaxIndex);
|
||||||
|
|
||||||
|
// Если зум слишком глубокий (менее 100 точек) - загружаем детальные данные
|
||||||
|
var pointsInView = newMaxIndex - newMinIndex + 1;
|
||||||
|
if (pointsInView < 100 && newMinIndex < newMaxIndex) {
|
||||||
|
// Определяем диапазон дат
|
||||||
|
var originalLabels = chart{{ metricName|replace({'-': '_', '.': '_'}) }}._originalLabels;
|
||||||
|
if (!originalLabels) {
|
||||||
|
originalLabels = chart{{ metricName|replace({'-': '_', '.': '_'}) }}._originalLabels = [...chart.data.labels];
|
||||||
|
}
|
||||||
|
|
||||||
|
var startTime = originalLabels[newMinIndex];
|
||||||
|
var endTime = originalLabels[newMaxIndex];
|
||||||
|
|
||||||
|
// Загружаем детальные данные
|
||||||
|
loadDetailedMetrics{{ metricName|replace({'-': '_', '.': '_'}) }}(startTime, endTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
pan: {
|
pan: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|
@ -815,6 +847,33 @@ const chart{{ metricName|replace({'-': '_', '.': '_'}) }} = new Chart(ctx{{ metr
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Функция загрузки детальных данных при зуме
|
||||||
|
function loadDetailedMetrics{{ metricName|replace({'-': '_', '.': '_'}) }}(startTime, endTime) {
|
||||||
|
var chart = chart{{ metricName|replace({'-': '_', '.': '_'}) }};
|
||||||
|
var metricName = '{{ metricName }}';
|
||||||
|
var serverId = {{ server.id }};
|
||||||
|
|
||||||
|
// Debounce - не запрашивать слишком часто
|
||||||
|
if (loadDetailedMetrics{{ metricName|replace({'-': '_', '.': '_'}) }}._loading) return;
|
||||||
|
loadDetailedMetrics{{ metricName|replace({'-': '_', '.': '_'}) }}._loading = true;
|
||||||
|
setTimeout(function() { loadDetailedMetrics{{ metricName|replace({'-': '_', '.': '_'}) }}._loading = false; }, 500);
|
||||||
|
|
||||||
|
var url = '/api/servers/' + serverId + '/metrics?start=' + encodeURIComponent(startTime) + '&end=' + encodeURIComponent(endTime);
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(function(response) { return response.json(); })
|
||||||
|
.then(function(data) {
|
||||||
|
if (data.labels && data.datasets && data.datasets[metricName]) {
|
||||||
|
chart.data.labels = data.labels;
|
||||||
|
chart.data.datasets[0].data = data.datasets[metricName];
|
||||||
|
chart.update();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
console.log('Failed to load detailed metrics for ' + metricName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Скрывать tooltip при уходе курсора с canvas в любую сторону
|
// Скрывать tooltip при уходе курсора с canvas в любую сторону
|
||||||
chart{{ metricName|replace({'-': '_', '.': '_'}) }}.canvas.addEventListener('mouseleave', function() {
|
chart{{ metricName|replace({'-': '_', '.': '_'}) }}.canvas.addEventListener('mouseleave', function() {
|
||||||
var tooltipEl = document.getElementById('chartjs-tooltip-{{ server.id }}-{{ metricName }}');
|
var tooltipEl = document.getElementById('chartjs-tooltip-{{ server.id }}-{{ metricName }}');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue