feat: Migrate Chart.js libraries to npm for offline usage and update application setup
This commit is contained in:
parent
e0192453d8
commit
bd0e169757
|
@ -0,0 +1,107 @@
|
|||
# Offline Usage Configuration
|
||||
|
||||
## Overview
|
||||
The application has been configured to work completely offline without any CDN dependencies.
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Chart.js Libraries Migration
|
||||
**Before (CDN Dependencies):**
|
||||
- Chart.js loaded from `https://cdn.jsdelivr.net/npm/chart.js@3.9.1`
|
||||
- Luxon from `https://cdn.jsdelivr.net/npm/luxon@2`
|
||||
- Chart.js adapter from `https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.3.1`
|
||||
- Zoom plugin from `https://unpkg.com/chartjs-plugin-zoom@1.2.1`
|
||||
- Streaming plugin from `https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming@2.0.0`
|
||||
|
||||
**After (NPM Dependencies):**
|
||||
All Chart.js libraries are now installed as npm packages and bundled with the application:
|
||||
```json
|
||||
"chart.js": "^3.9.1",
|
||||
"chartjs-adapter-luxon": "^1.3.1",
|
||||
"chartjs-plugin-streaming": "^2.0.0",
|
||||
"chartjs-plugin-zoom": "^1.2.1",
|
||||
"luxon": "^2.5.2"
|
||||
```
|
||||
|
||||
### 2. Chart.js Setup Module
|
||||
Created `frontend/src/utils/chartSetup.js` that:
|
||||
- Imports all Chart.js components as ES modules
|
||||
- Registers all required plugins (zoom, streaming, time scales)
|
||||
- Makes Chart.js available globally for existing components
|
||||
- Provides console confirmation of successful setup
|
||||
|
||||
### 3. Application Entry Point
|
||||
Modified `frontend/src/main.jsx` to import the Chart.js setup before rendering the application.
|
||||
|
||||
### 4. Updated HTML Template
|
||||
Removed all CDN script tags from `frontend/index.html`.
|
||||
|
||||
## Verification
|
||||
|
||||
### Build Verification
|
||||
The application builds successfully without any external dependencies:
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Development Server
|
||||
The development server runs without internet connection:
|
||||
```bash
|
||||
cd frontend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Runtime Verification
|
||||
- No network requests to external CDNs
|
||||
- All Chart.js functionality preserved (zooming, streaming, real-time plots)
|
||||
- Completely self-contained in bundled JavaScript
|
||||
|
||||
## Backend Offline Compliance
|
||||
|
||||
The Python backend already uses only local dependencies:
|
||||
- Flask for web server
|
||||
- python-snap7 for PLC communication
|
||||
- Local file-based configuration
|
||||
- No external API calls or services
|
||||
|
||||
## Deployment for Offline Use
|
||||
|
||||
### Frontend Production Build
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
The `dist/` folder contains all necessary files with no external dependencies.
|
||||
|
||||
### Complete Offline Package
|
||||
The entire application (backend + frontend) can be deployed on systems without internet access:
|
||||
|
||||
1. **Python Requirements**: Install from `requirements.txt`
|
||||
2. **Frontend**: Use built files from `dist/` folder
|
||||
3. **PLC Communication**: Requires `snap7.dll` in system PATH
|
||||
4. **Configuration**: All JSON-based, stored locally
|
||||
|
||||
## Chart.js Feature Compatibility
|
||||
|
||||
All existing Chart.js features remain functional:
|
||||
- ✅ Real-time streaming plots
|
||||
- ✅ Zoom and pan functionality
|
||||
- ✅ Time-based X-axis with Luxon adapter
|
||||
- ✅ Multiple dataset support
|
||||
- ✅ Dynamic color assignment
|
||||
- ✅ Plot session management
|
||||
- ✅ CSV data export integration
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Global vs ES Module Access
|
||||
The setup maintains backward compatibility by making Chart.js available both ways:
|
||||
- **Global**: `window.Chart` (for existing components)
|
||||
- **ES Module**: `import ChartJS from './utils/chartSetup.js'` (for new components)
|
||||
|
||||
### Bundle Size Impact
|
||||
The Chart.js libraries add approximately ~400KB to the bundle (gzipped), which is acceptable for offline industrial applications.
|
||||
|
||||
### Browser Compatibility
|
||||
All dependencies support modern browsers without requiring polyfills for the target deployment environment.
|
|
@ -1309,8 +1309,181 @@
|
|||
"udp_port": 9870,
|
||||
"datasets_available": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:43:38.226776",
|
||||
"level": "info",
|
||||
"event_type": "application_started",
|
||||
"message": "Application initialization completed successfully",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:43:38.387187",
|
||||
"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-14T18:43:38.390197",
|
||||
"level": "info",
|
||||
"event_type": "dataset_activated",
|
||||
"message": "Dataset activated: Fast",
|
||||
"details": {
|
||||
"dataset_id": "Fast",
|
||||
"variables_count": 1,
|
||||
"streaming_count": 1,
|
||||
"prefix": "fast"
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:43:38.393188",
|
||||
"level": "info",
|
||||
"event_type": "csv_recording_started",
|
||||
"message": "CSV recording started: 2 datasets activated",
|
||||
"details": {
|
||||
"activated_datasets": 2,
|
||||
"total_datasets": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:43:38.396188",
|
||||
"level": "info",
|
||||
"event_type": "udp_streaming_started",
|
||||
"message": "UDP streaming to PlotJuggler started",
|
||||
"details": {
|
||||
"udp_host": "127.0.0.1",
|
||||
"udp_port": 9870,
|
||||
"datasets_available": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:45:55.386410",
|
||||
"level": "info",
|
||||
"event_type": "application_started",
|
||||
"message": "Application initialization completed successfully",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:45:55.480823",
|
||||
"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-14T18:45:55.484826",
|
||||
"level": "info",
|
||||
"event_type": "dataset_activated",
|
||||
"message": "Dataset activated: Fast",
|
||||
"details": {
|
||||
"dataset_id": "Fast",
|
||||
"variables_count": 1,
|
||||
"streaming_count": 1,
|
||||
"prefix": "fast"
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:45:55.486826",
|
||||
"level": "info",
|
||||
"event_type": "csv_recording_started",
|
||||
"message": "CSV recording started: 2 datasets activated",
|
||||
"details": {
|
||||
"activated_datasets": 2,
|
||||
"total_datasets": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:45:55.488826",
|
||||
"level": "info",
|
||||
"event_type": "udp_streaming_started",
|
||||
"message": "UDP streaming to PlotJuggler started",
|
||||
"details": {
|
||||
"udp_host": "127.0.0.1",
|
||||
"udp_port": 9870,
|
||||
"datasets_available": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:46:16.497318",
|
||||
"level": "info",
|
||||
"event_type": "application_started",
|
||||
"message": "Application initialization completed successfully",
|
||||
"details": {}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:46:16.610938",
|
||||
"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-14T18:46:16.613936",
|
||||
"level": "info",
|
||||
"event_type": "dataset_activated",
|
||||
"message": "Dataset activated: Fast",
|
||||
"details": {
|
||||
"dataset_id": "Fast",
|
||||
"variables_count": 1,
|
||||
"streaming_count": 1,
|
||||
"prefix": "fast"
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:46:16.616946",
|
||||
"level": "info",
|
||||
"event_type": "csv_recording_started",
|
||||
"message": "CSV recording started: 2 datasets activated",
|
||||
"details": {
|
||||
"activated_datasets": 2,
|
||||
"total_datasets": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:46:16.620459",
|
||||
"level": "info",
|
||||
"event_type": "udp_streaming_started",
|
||||
"message": "UDP streaming to PlotJuggler started",
|
||||
"details": {
|
||||
"udp_host": "127.0.0.1",
|
||||
"udp_port": 9870,
|
||||
"datasets_available": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-08-14T18:46:27.723966",
|
||||
"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"
|
||||
],
|
||||
"time_window": 20,
|
||||
"trigger_variable": null,
|
||||
"auto_started": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"last_updated": "2025-08-14T18:32:34.863727",
|
||||
"total_entries": 138
|
||||
"last_updated": "2025-08-14T18:46:27.723966",
|
||||
"total_entries": 154
|
||||
}
|
|
@ -12,12 +12,7 @@
|
|||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<!-- Chart.js Libraries - Load in strict order (compatible versions) -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/luxon@2"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.3.1"></script>
|
||||
<script src="https://unpkg.com/chartjs-plugin-zoom@1.2.1/dist/chartjs-plugin-zoom.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming@2.0.0"></script>
|
||||
<!-- Chart.js Libraries now loaded via npm modules -->
|
||||
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
|
|
|
@ -15,7 +15,12 @@
|
|||
"@rjsf/chakra-ui": "^5.24.12",
|
||||
"@rjsf/core": "^5.24.12",
|
||||
"@rjsf/validator-ajv8": "^5.24.12",
|
||||
"chart.js": "^3.9.1",
|
||||
"chartjs-adapter-luxon": "^1.3.1",
|
||||
"chartjs-plugin-streaming": "^2.0.0",
|
||||
"chartjs-plugin-zoom": "^1.2.1",
|
||||
"framer-motion": "^11.2.12",
|
||||
"luxon": "^2.5.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^5.5.0",
|
||||
|
|
|
@ -5,6 +5,9 @@ import { BrowserRouter } from 'react-router-dom'
|
|||
import { ChakraProvider, ColorModeScript } from '@chakra-ui/react'
|
||||
import theme from './theme.js'
|
||||
|
||||
// Initialize Chart.js for offline usage
|
||||
import './utils/chartSetup.js'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Chart.js Setup for Offline Usage
|
||||
* Replaces CDN dependencies with npm modules
|
||||
*/
|
||||
|
||||
// Import Chart.js and all required plugins
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
LineController,
|
||||
BarController,
|
||||
BarElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
TimeScale,
|
||||
TimeSeriesScale,
|
||||
Filler
|
||||
} from 'chart.js';
|
||||
|
||||
// Import time adapter
|
||||
import 'chartjs-adapter-luxon';
|
||||
|
||||
// Import plugins
|
||||
import zoomPlugin from 'chartjs-plugin-zoom';
|
||||
import streamingPlugin from 'chartjs-plugin-streaming';
|
||||
|
||||
// Register all Chart.js components
|
||||
ChartJS.register(
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
LineController,
|
||||
BarController,
|
||||
BarElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
TimeScale,
|
||||
TimeSeriesScale,
|
||||
Filler,
|
||||
zoomPlugin,
|
||||
streamingPlugin
|
||||
);
|
||||
|
||||
// Make Chart.js available globally for existing components
|
||||
window.Chart = ChartJS;
|
||||
|
||||
// Export for ES module usage
|
||||
export default ChartJS;
|
||||
export { ChartJS };
|
||||
|
||||
// Initialize Chart.js setup
|
||||
console.log('📊 Chart.js setup complete - all plugins registered');
|
|
@ -4,10 +4,10 @@
|
|||
"should_stream": true,
|
||||
"active_datasets": [
|
||||
"Test",
|
||||
"DAR",
|
||||
"Fast"
|
||||
"Fast",
|
||||
"DAR"
|
||||
]
|
||||
},
|
||||
"auto_recovery_enabled": true,
|
||||
"last_update": "2025-08-14T18:32:34.865706"
|
||||
"last_update": "2025-08-14T18:46:16.622461"
|
||||
}
|
Loading…
Reference in New Issue