diff --git a/vna_system/web_ui/static/js/modules/charts.js b/vna_system/web_ui/static/js/modules/charts.js
index 94aa3bd..696df70 100644
--- a/vna_system/web_ui/static/js/modules/charts.js
+++ b/vna_system/web_ui/static/js/modules/charts.js
@@ -174,6 +174,9 @@ export class ChartManager {
+
@@ -181,6 +184,7 @@ export class ChartManager {
+
@@ -213,6 +217,7 @@ export class ChartManager {
e.stopPropagation();
switch (action) {
case 'fullscreen': this.toggleFullscreen(processorId); break;
+ case 'upload': this.uploadHistory(processorId); break;
case 'download': this.downloadChart(processorId); break;
case 'hide':
this.hideChart(processorId);
@@ -220,6 +225,14 @@ export class ChartManager {
break;
}
});
+
+ // Setup file input handler
+ const fileInput = card.querySelector(`#historyFileInput_${processorId}`);
+ if (fileInput) {
+ fileInput.addEventListener('change', async (e) => {
+ await this.handleHistoryUpload(processorId, e);
+ });
+ }
}
updateChartMetadata(processorId) {
@@ -377,6 +390,71 @@ export class ChartManager {
};
}
+ uploadHistory(processorId) {
+ const chart = this.charts.get(processorId);
+ if (!chart) return;
+
+ const fileInput = chart.element.querySelector(`#historyFileInput_${processorId}`);
+ if (fileInput) {
+ fileInput.click();
+ }
+ }
+
+ async handleHistoryUpload(processorId, event) {
+ const file = event.target.files?.[0];
+ if (!file) return;
+
+ try {
+ const text = await file.text();
+ const jsonData = JSON.parse(text);
+
+ // Extract sweep_history from the saved JSON file
+ const sweepHistory = jsonData.sweep_history || [];
+
+ if (!sweepHistory || sweepHistory.length === 0) {
+ this.notifications?.show?.({
+ type: 'error',
+ title: 'Ошибка загрузки',
+ message: 'Файл не содержит истории свипов'
+ });
+ return;
+ }
+
+ // Send load_history message via WebSocket
+ const websocket = window.vnaDashboard?.websocket;
+ if (websocket && websocket.ws && websocket.ws.readyState === WebSocket.OPEN) {
+ websocket.ws.send(JSON.stringify({
+ type: 'load_history',
+ processor_id: processorId,
+ history_data: sweepHistory
+ }));
+
+ this.notifications?.show?.({
+ type: 'success',
+ title: 'История загружена',
+ message: `Загружено ${sweepHistory.length} записей для ${formatProcessorName(processorId)}`
+ });
+ } else {
+ this.notifications?.show?.({
+ type: 'error',
+ title: 'Ошибка подключения',
+ message: 'WebSocket не подключен'
+ });
+ }
+
+ } catch (err) {
+ console.error('Error loading history:', err);
+ this.notifications?.show?.({
+ type: 'error',
+ title: 'Ошибка загрузки',
+ message: `Не удалось прочитать файл: ${err.message}`
+ });
+ }
+
+ // Reset file input
+ event.target.value = '';
+ }
+
destroy() {
console.log('Cleaning up Chart Manager...');
this.clearAll();
diff --git a/vna_system/web_ui/static/js/modules/charts/chart-settings.js b/vna_system/web_ui/static/js/modules/charts/chart-settings.js
index 206ae33..17a3118 100644
--- a/vna_system/web_ui/static/js/modules/charts/chart-settings.js
+++ b/vna_system/web_ui/static/js/modules/charts/chart-settings.js
@@ -63,22 +63,11 @@ export class ChartSettingsManager {
this.updateParametersSelectively(processorId, settingsContainer, uiParameters);
} else {
// Initial render: full rebuild
- const loadHistoryButton = `
-
-
-
-
- `;
-
- const settingsHtml = loadHistoryButton + uiParameters.map(param =>
+ const settingsHtml = uiParameters.map(param =>
createParameterControl(param, processorId, 'chart')
).join('');
settingsContainer.innerHTML = settingsHtml;
this.setupEvents(settingsContainer, processorId);
- this.setupLoadHistoryButton(processorId);
}
// Initialize last values
@@ -293,72 +282,6 @@ export class ChartSettingsManager {
}, 1000);
}
- setupLoadHistoryButton(processorId) {
- const loadBtn = document.getElementById(`loadHistoryBtn_${processorId}`);
- const fileInput = document.getElementById(`historyFileInput_${processorId}`);
-
- if (!loadBtn || !fileInput) return;
-
- loadBtn.addEventListener('click', () => {
- fileInput.click();
- });
-
- fileInput.addEventListener('change', async (e) => {
- const file = e.target.files?.[0];
- if (!file) return;
-
- try {
- const text = await file.text();
- const jsonData = JSON.parse(text);
-
- // Extract sweep_history from the saved JSON file
- const sweepHistory = jsonData.sweep_history || [];
-
- if (!sweepHistory || sweepHistory.length === 0) {
- window.vnaDashboard?.notifications?.show?.({
- type: 'error',
- title: 'Ошибка загрузки',
- message: 'Файл не содержит истории свипов'
- });
- return;
- }
-
- // Send load_history message via WebSocket
- const websocket = window.vnaDashboard?.websocket;
- if (websocket && websocket.ws && websocket.ws.readyState === WebSocket.OPEN) {
- websocket.ws.send(JSON.stringify({
- type: 'load_history',
- processor_id: processorId,
- history_data: sweepHistory
- }));
-
- window.vnaDashboard?.notifications?.show?.({
- type: 'success',
- title: 'История загружена',
- message: `Загружено ${sweepHistory.length} записей для ${processorId}`
- });
- } else {
- window.vnaDashboard?.notifications?.show?.({
- type: 'error',
- title: 'Ошибка подключения',
- message: 'WebSocket не подключен'
- });
- }
-
- } catch (err) {
- console.error('Error loading history:', err);
- window.vnaDashboard?.notifications?.show?.({
- type: 'error',
- title: 'Ошибка загрузки',
- message: `Не удалось прочитать файл: ${err.message}`
- });
- }
-
- // Reset file input
- fileInput.value = '';
- });
- }
-
destroy() {
// Clear timers
Object.keys(this.settingDebounceTimers).forEach(key => {