From 405edd682eb025d9643dc28c52c8a94f21d7bd30 Mon Sep 17 00:00:00 2001 From: Miguel Date: Fri, 15 Aug 2025 15:49:13 +0200 Subject: [PATCH] feat: Enhance logging and configuration for plot sessions, update dataset handling, and improve chart rendering logic --- application_events.json | 883 +++++++++++++++++- config/data/plot_definitions.json | 8 +- frontend/src/components/ChartjsPlot.jsx | 106 ++- .../src/components/PlotRealtimeSession.jsx | 28 +- system_state.json | 6 +- 5 files changed, 971 insertions(+), 60 deletions(-) diff --git a/application_events.json b/application_events.json index 933fd19..30b9a99 100644 --- a/application_events.json +++ b/application_events.json @@ -5146,8 +5146,887 @@ "trigger_variable": null, "auto_started": true } + }, + { + "timestamp": "2025-08-15T13:17:30.394540", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 10, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T13:17:36.212527", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 10, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T13:17:58.978488", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T13:18:03.031314", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T13:20:54.142912", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-15T13:20:54.207454", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: DAR", + "details": { + "dataset_id": "DAR", + "variables_count": 2, + "streaming_count": 2, + "prefix": "gateway_phoenix" + } + }, + { + "timestamp": "2025-08-15T13:20:54.216389", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: Fast", + "details": { + "dataset_id": "Fast", + "variables_count": 2, + "streaming_count": 1, + "prefix": "fast" + } + }, + { + "timestamp": "2025-08-15T13:20:54.226392", + "level": "info", + "event_type": "csv_recording_started", + "message": "CSV recording started: 2 datasets activated", + "details": { + "activated_datasets": 2, + "total_datasets": 3 + } + }, + { + "timestamp": "2025-08-15T13:21:00.678436", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T13:21:08.721840", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T13:21:11.289241", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T14:56:09.985830", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T14:56:18.219453", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T14:56:21.037864", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T14:58:34.874001", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 100, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T14:59:59.138084", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 3600, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:00:07.615193", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 3600, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:00:30.893455", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:00:38.278238", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:01:32.643536", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:03:00.348122", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:04:31.666815", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:04:49.237503", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:05:38.716154", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:08:19.565944", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-15T15:08:19.660559", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: DAR", + "details": { + "dataset_id": "DAR", + "variables_count": 2, + "streaming_count": 2, + "prefix": "gateway_phoenix" + } + }, + { + "timestamp": "2025-08-15T15:08:19.672556", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: Fast", + "details": { + "dataset_id": "Fast", + "variables_count": 2, + "streaming_count": 1, + "prefix": "fast" + } + }, + { + "timestamp": "2025-08-15T15:08:19.680317", + "level": "info", + "event_type": "csv_recording_started", + "message": "CSV recording started: 2 datasets activated", + "details": { + "activated_datasets": 2, + "total_datasets": 3 + } + }, + { + "timestamp": "2025-08-15T15:08:34.489474", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:08:41.168670", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:08:46.141122", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:08:49.523888", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:09:02.390524", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:09:11.497406", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:09:53.182024", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:09:58.404845", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:10:05.667707", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:10:12.834883", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:10:22.809370", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:13:06.842781", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:13:14.103363", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:18:52.838437", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-15T15:18:52.889546", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: DAR", + "details": { + "dataset_id": "DAR", + "variables_count": 2, + "streaming_count": 2, + "prefix": "gateway_phoenix" + } + }, + { + "timestamp": "2025-08-15T15:18:52.896544", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: Fast", + "details": { + "dataset_id": "Fast", + "variables_count": 2, + "streaming_count": 1, + "prefix": "fast" + } + }, + { + "timestamp": "2025-08-15T15:18:52.905110", + "level": "info", + "event_type": "csv_recording_started", + "message": "CSV recording started: 2 datasets activated", + "details": { + "activated_datasets": 2, + "total_datasets": 3 + } + }, + { + "timestamp": "2025-08-15T15:19:01.374281", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:19:06.187319", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:19:10.659288", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:19:59.587418", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:20:04.064134", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:20:14.895606", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:48:00.666925", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:48:45.628577", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } + }, + { + "timestamp": "2025-08-15T15:48:55.687372", + "level": "info", + "event_type": "plot_session_created", + "message": "Plot session 'UR29' created and started", + "details": { + "session_id": "plot_1", + "variables": [ + "UR29_Brix", + "UR29_ma", + "AUX Blink_1.0S", + "AUX Blink_1.6S" + ], + "time_window": 36, + "trigger_variable": null, + "auto_started": true + } } ], - "last_updated": "2025-08-15T13:15:29.776996", - "total_entries": 445 + "last_updated": "2025-08-15T15:48:55.687372", + "total_entries": 499 } \ No newline at end of file diff --git a/config/data/plot_definitions.json b/config/data/plot_definitions.json index f6a3565..958775b 100644 --- a/config/data/plot_definitions.json +++ b/config/data/plot_definitions.json @@ -5,10 +5,10 @@ "line_tension": 0, "name": "UR29", "point_hover_radius": 4, - "point_radius": 0, - "stacked": false, - "stepped": true, - "time_window": 10, + "point_radius": 2.5, + "stacked": true, + "stepped": false, + "time_window": 36, "trigger_enabled": false, "trigger_on_true": true, "trigger_variable": null, diff --git a/frontend/src/components/ChartjsPlot.jsx b/frontend/src/components/ChartjsPlot.jsx index d7cfadf..7ef0a18 100644 --- a/frontend/src/components/ChartjsPlot.jsx +++ b/frontend/src/components/ChartjsPlot.jsx @@ -66,7 +66,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => { const [dataPointsCount, setDataPointsCount] = useState(0); const [isRefreshing, setIsRefreshing] = useState(false); const [isLoadingHistorical, setIsLoadingHistorical] = useState(false); - const [isZoomEnabled, setIsZoomEnabled] = useState(true); + const [isZoomEnabled, setIsZoomEnabled] = useState(false); const resolvedConfigRef = useRef(null); // Chart health monitoring @@ -117,7 +117,8 @@ const ChartjsPlot = ({ session, height = '400px' }) => { name: varConfig.variable_name, label: varConfig.label || varConfig.variable_name, // Use display label if available color: varConfig.color || getColor(varConfig.variable_name, index), - enabled: varConfig.enabled !== false + enabled: varConfig.enabled !== false, + y_axis: varConfig.y_axis || 'left' // Include Y-axis positioning })); } // Handle simple array of strings @@ -125,7 +126,8 @@ const ChartjsPlot = ({ session, height = '400px' }) => { name: variable, label: variable, // For simple strings, name and label are the same color: getColor(variable, index), - enabled: true + enabled: true, + y_axis: 'left' // Default for simple strings })); } else if (typeof variables === 'object') { const firstVarConfig = Object.values(variables)[0]; @@ -136,7 +138,8 @@ const ChartjsPlot = ({ session, height = '400px' }) => { name: config.variable_name, label: config.label || config.variable_name, // Use display label if available color: config.color || getColor(config.variable_name), - enabled: config.enabled !== false + enabled: config.enabled !== false, + y_axis: config.y_axis || 'left' // Include Y-axis positioning })); } else { return Object.entries(variables) @@ -144,7 +147,8 @@ const ChartjsPlot = ({ session, height = '400px' }) => { .map(([name, config]) => ({ name: name, color: config.color || getColor(name), - enabled: config.enabled !== false + enabled: config.enabled !== false, + y_axis: config.y_axis || 'left' // Include Y-axis positioning })); } } @@ -614,8 +618,10 @@ const ChartjsPlot = ({ session, height = '400px' }) => { pointHoverRadius: pointHoverRadius, tension: lineTension, stepped: stepped, - // When stacked is enabled, assign each dataset to its own Y axis for multi-axis visualization - ...(useStackedAxes ? { yAxisID: `y-axis-${index}` } : {}) + // Assign Y axis based on configuration and mode + yAxisID: useStackedAxes + ? `y-axis-${index}` // Stacked mode: each variable gets its own axis + : (variableInfo.y_axis === 'right' ? 'y-right' : 'y-left') // Non-stacked: use left/right configuration }; }); @@ -734,22 +740,22 @@ const ChartjsPlot = ({ session, height = '400px' }) => { const variableName = variable.name || variable.label || `Variable ${index}`; const color = variable.color || getColor(variableName, index); - // Improved Y-axis positioning logic for better visual distribution - // Distribute axes more evenly: left, right, left, right, etc. - // But group consecutive axes to avoid overcrowding - const totalAxes = enabledVariables.length; + // Respect the y_axis configuration from variable settings + // If y_axis is specified, use it; otherwise use intelligent distribution let position; - - if (totalAxes <= 2) { - // With 1-2 axes, alternate left/right - position = index === 0 ? 'left' : 'right'; - } else if (totalAxes <= 4) { - // With 3-4 axes, use pattern: left, right, left, right - position = index % 2 === 0 ? 'left' : 'right'; + if (variable.y_axis === 'left' || variable.y_axis === 'right') { + position = variable.y_axis; } else { - // With 5+ axes, group them: first half on left, second half on right - const halfPoint = Math.ceil(totalAxes / 2); - position = index < halfPoint ? 'left' : 'right'; + // Fallback to intelligent distribution for variables without y_axis config + const totalAxes = enabledVariables.length; + if (totalAxes <= 2) { + position = index === 0 ? 'left' : 'right'; + } else if (totalAxes <= 4) { + position = index % 2 === 0 ? 'left' : 'right'; + } else { + const halfPoint = Math.ceil(totalAxes / 2); + position = index < halfPoint ? 'left' : 'right'; + } } scales[`y-axis-${index}`] = { @@ -799,15 +805,33 @@ const ChartjsPlot = ({ session, height = '400px' }) => { max: yMaxInitial } } - : // Default single Y axis + : // Non-stacked mode with left/right Y axes { - y: { + 'y-left': { + type: 'linear', + position: 'left', title: { display: true, - text: 'Valor' + text: 'Valor (Left)' }, min: yMinInitial, - max: yMaxInitial + max: yMaxInitial, + grid: { + drawOnChartArea: true + } + }, + 'y-right': { + type: 'linear', + position: 'right', + title: { + display: true, + text: 'Valor (Right)' + }, + min: yMinInitial, + max: yMaxInitial, + grid: { + drawOnChartArea: false // Don't draw grid for right axis to avoid overlap + } } } ) @@ -1381,31 +1405,25 @@ const ChartjsPlot = ({ session, height = '400px' }) => { } }, [session, getEnabledVariables, loadHistoricalData, normalizeTimestamp]); - // Update configuration directly (for real-time style changes) + // Update configuration (always recreates chart for simplicity and reliability) const updateConfig = useCallback(async (newConfig) => { try { console.log(`🔄 Updating configuration for plot session ${session?.session_id}...`); + console.log(`📋 New config received:`, newConfig); const oldConfig = resolvedConfigRef.current; - resolvedConfigRef.current = { ...oldConfig, ...newConfig }; + console.log(`📋 Old config:`, oldConfig); + + // Merge new config with current configuration + const mergedConfig = { ...oldConfig, ...newConfig }; + console.log(`📋 Merged config:`, mergedConfig); + + resolvedConfigRef.current = mergedConfig; - // Check if chart recreation is needed - const needsRecreation = !oldConfig || - oldConfig.line_tension !== newConfig.line_tension || - oldConfig.stepped !== newConfig.stepped || - oldConfig.stacked !== newConfig.stacked || - oldConfig.point_radius !== newConfig.point_radius || - oldConfig.point_hover_radius !== newConfig.point_hover_radius || - oldConfig.time_window !== newConfig.time_window || - oldConfig.y_min !== newConfig.y_min || - oldConfig.y_max !== newConfig.y_max; - - if (needsRecreation) { - console.log(`🔄 Chart needs recreation due to configuration changes`); - await createStreamingChart(); - } else { - console.log(`✅ No chart recreation needed, configuration updated`); - } + // Always recreate chart to ensure all changes are applied correctly + console.log(`� Recreating chart to apply configuration changes...`); + await createStreamingChart(); + console.log(`✅ Chart recreated successfully with new configuration`); } catch (error) { console.error(`❌ Error updating configuration for plot session ${session?.session_id}:`, error); setError(error.message); diff --git a/frontend/src/components/PlotRealtimeSession.jsx b/frontend/src/components/PlotRealtimeSession.jsx index 1abd5b2..0dae44d 100644 --- a/frontend/src/components/PlotRealtimeSession.jsx +++ b/frontend/src/components/PlotRealtimeSession.jsx @@ -298,17 +298,31 @@ export default function PlotRealtimeSession({ try { console.log(`🔄 Applying configuration changes for plot ${plotDefinition.id}...`) console.log(`📊 Plot was active: ${wasActive}, paused: ${wasPaused}`) + console.log(`📋 Local config to apply:`, localConfig) - // Update backend configuration + // First, update backend configuration and wait for it to complete + console.log(`💾 Saving configuration to backend...`) await onConfigUpdate?.(plotDefinition.id, localConfig) + console.log(`✅ Configuration saved to backend successfully`) - // Apply changes to chart if possible - if (chartControlsRef.current?.updateConfig) { - chartControlsRef.current.updateConfig(localConfig) + // Wait a moment for the configuration to be fully persisted + await new Promise(resolve => setTimeout(resolve, 200)) + + // Then reload configuration from backend (same as Refresh button) + if (onReloadConfig) { + console.log(`📥 Reloading plot configuration from backend...`) + await onReloadConfig() + console.log(`✅ Configuration reloaded from backend`) } - // Wait a moment for the configuration to be applied - await new Promise(resolve => setTimeout(resolve, 500)) + // Finally refresh the chart configuration (same as Refresh button) + if (chartControlsRef.current?.refreshConfiguration) { + console.log(`🔄 Refreshing chart configuration...`) + await chartControlsRef.current.refreshConfiguration() + console.log(`✅ Chart configuration refreshed successfully`) + } else { + console.warn(`⚠️ chartControlsRef.current.refreshConfiguration not available`) + } // Refresh session status to get the latest state await refreshSessionStatus() @@ -340,7 +354,7 @@ export default function PlotRealtimeSession({ applyingChangesRef.current = false }, 1000) } - }, [plotDefinition.id, localConfig, onConfigUpdate, session.is_active, session.is_paused, refreshSessionStatus, handleControlClick, toast]) + }, [plotDefinition.id, localConfig, onConfigUpdate, onReloadConfig, session.is_active, session.is_paused, refreshSessionStatus, handleControlClick, toast]) const resetConfigChanges = () => { setLocalConfig({ diff --git a/system_state.json b/system_state.json index e92b6bb..a3144e9 100644 --- a/system_state.json +++ b/system_state.json @@ -3,11 +3,11 @@ "should_connect": true, "should_stream": false, "active_datasets": [ - "Test", "Fast", - "DAR" + "DAR", + "Test" ] }, "auto_recovery_enabled": true, - "last_update": "2025-08-15T13:14:31.493157" + "last_update": "2025-08-15T15:18:52.911110" } \ No newline at end of file