feat: Implement simulation analysis data display and dashboard element configuration
This commit is contained in:
@@ -121,7 +121,7 @@ const AnalyzerManager: React.FC = () => {
|
|||||||
|
|
||||||
if (hasValidData) {
|
if (hasValidData) {
|
||||||
const currentGraphData = element.graphData || [];
|
const currentGraphData = element.graphData || [];
|
||||||
const newGraphData = [...currentGraphData, newPoint].slice(-20);
|
const newGraphData = [...currentGraphData, newPoint].slice(-10);
|
||||||
|
|
||||||
// Always update for single-machine as we are appending time-series data
|
// Always update for single-machine as we are appending time-series data
|
||||||
updateGraphData(block.blockUuid, element.elementUuid, newGraphData);
|
updateGraphData(block.blockUuid, element.elementUuid, newGraphData);
|
||||||
|
|||||||
@@ -533,7 +533,6 @@ const ElementEditor: React.FC<ElementEditorProps> = ({
|
|||||||
updateElementData(selectedBlock, selectedElement, { label: value });
|
updateElementData(selectedBlock, selectedElement, { label: value });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<InputWithDropDown label="Title" value={`title`} placeholder={"Label 1"} min={0.1} step={0.1} max={2} onChange={() => { }} />
|
|
||||||
<div className="data">
|
<div className="data">
|
||||||
<DataDetailedDropdown
|
<DataDetailedDropdown
|
||||||
title="Data Source"
|
title="Data Source"
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ function Analyzer() {
|
|||||||
const timestamp = new Date().toISOString();
|
const timestamp = new Date().toISOString();
|
||||||
const newEntry = {
|
const newEntry = {
|
||||||
timestamp,
|
timestamp,
|
||||||
isActive: conveyor.isActive,
|
isActive: !conveyor.isPaused,
|
||||||
speed: conveyor.speed,
|
speed: conveyor.speed,
|
||||||
state: conveyor.state,
|
state: conveyor.state,
|
||||||
materialsCount: materialFlow.currentMaterials,
|
materialsCount: materialFlow.currentMaterials,
|
||||||
@@ -306,7 +306,7 @@ function Analyzer() {
|
|||||||
assetType: "conveyor",
|
assetType: "conveyor",
|
||||||
|
|
||||||
currentStatus: {
|
currentStatus: {
|
||||||
isActive: conveyor.isActive,
|
isActive: !conveyor.isPaused,
|
||||||
isPaused: conveyor.isPaused,
|
isPaused: conveyor.isPaused,
|
||||||
state: conveyor.state,
|
state: conveyor.state,
|
||||||
speed: conveyor.speed,
|
speed: conveyor.speed,
|
||||||
@@ -427,16 +427,19 @@ function Analyzer() {
|
|||||||
// Update historical data
|
// Update historical data
|
||||||
const timestamp = new Date().toISOString();
|
const timestamp = new Date().toISOString();
|
||||||
const currentData = historicalDataRef.current[vehicle.modelUuid] || [];
|
const currentData = historicalDataRef.current[vehicle.modelUuid] || [];
|
||||||
historicalDataRef.current[vehicle.modelUuid] = [...currentData, {
|
historicalDataRef.current[vehicle.modelUuid] = [
|
||||||
timestamp,
|
...currentData,
|
||||||
phase: vehicle.currentPhase,
|
{
|
||||||
load: vehicle.currentLoad,
|
timestamp,
|
||||||
distanceTraveled: actualDistance,
|
phase: vehicle.currentPhase,
|
||||||
state: vehicle.state,
|
load: vehicle.currentLoad,
|
||||||
performance: performance.performanceRate,
|
distanceTraveled: actualDistance,
|
||||||
speed: vehicle.speed,
|
state: vehicle.state,
|
||||||
tripsCompleted,
|
performance: performance.performanceRate,
|
||||||
}].slice(-100);
|
speed: vehicle.speed,
|
||||||
|
tripsCompleted,
|
||||||
|
},
|
||||||
|
].slice(-100);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
assetId: vehicle.modelUuid,
|
assetId: vehicle.modelUuid,
|
||||||
@@ -698,15 +701,18 @@ function Analyzer() {
|
|||||||
// Update historical data
|
// Update historical data
|
||||||
const timestamp = new Date().toISOString();
|
const timestamp = new Date().toISOString();
|
||||||
const currentData = historicalDataRef.current[machine.modelUuid] || [];
|
const currentData = historicalDataRef.current[machine.modelUuid] || [];
|
||||||
historicalDataRef.current[machine.modelUuid] = [...currentData, {
|
historicalDataRef.current[machine.modelUuid] = [
|
||||||
timestamp,
|
...currentData,
|
||||||
processTime: actualProcessTime,
|
{
|
||||||
partsProcessed,
|
timestamp,
|
||||||
isActive: machine.isActive,
|
processTime: actualProcessTime,
|
||||||
state: machine.state,
|
partsProcessed,
|
||||||
defectRate,
|
isActive: machine.isActive,
|
||||||
performance: performance.performanceRate,
|
state: machine.state,
|
||||||
}].slice(-100);
|
defectRate,
|
||||||
|
performance: performance.performanceRate,
|
||||||
|
},
|
||||||
|
].slice(-100);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
assetId: machine.modelUuid,
|
assetId: machine.modelUuid,
|
||||||
@@ -1336,9 +1342,9 @@ function Analyzer() {
|
|||||||
const averageResidenceTime =
|
const averageResidenceTime =
|
||||||
materialHistoryRef.current.length > 0
|
materialHistoryRef.current.length > 0
|
||||||
? materialHistoryRef.current.reduce((sum, entry) => {
|
? materialHistoryRef.current.reduce((sum, entry) => {
|
||||||
const residenceTime = new Date(entry.removedAt).getTime() - (entry.material.startTime || 0);
|
const residenceTime = new Date(entry.removedAt).getTime() - (entry.material.startTime || 0);
|
||||||
return sum + (residenceTime || 0);
|
return sum + (residenceTime || 0);
|
||||||
}, 0) / materialHistoryRef.current.length
|
}, 0) / materialHistoryRef.current.length
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
// Bottleneck Identification
|
// Bottleneck Identification
|
||||||
@@ -1604,23 +1610,27 @@ function Analyzer() {
|
|||||||
// EFFECTS
|
// EFFECTS
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
const performAnalysisRef = useRef(performAnalysis);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
performAnalysisRef.current = performAnalysis;
|
||||||
|
}, [performAnalysis]);
|
||||||
|
|
||||||
// Perform initial analysis and set up interval
|
// Perform initial analysis and set up interval
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isPlaying) return;
|
if (!isPlaying) return;
|
||||||
// Initial analysis
|
|
||||||
performAnalysis();
|
|
||||||
|
|
||||||
// Set up periodic analysis (every 5 seconds)
|
// Set up periodic analysis (every 1 second)
|
||||||
analysisIntervalRef.current = setInterval(() => {
|
analysisIntervalRef.current = setInterval(() => {
|
||||||
performAnalysis();
|
performAnalysisRef.current();
|
||||||
}, 5000);
|
}, 1000);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (analysisIntervalRef.current) {
|
if (analysisIntervalRef.current) {
|
||||||
clearInterval(analysisIntervalRef.current);
|
clearInterval(analysisIntervalRef.current);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [isPlaying, conveyors, vehicles, armBots, machines, humans, cranes, materials]);
|
}, [isPlaying]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user