added comparsion data
This commit is contained in:
@@ -2,205 +2,211 @@ import React, { useEffect, useMemo, useState } from "react";
|
||||
import PerformanceResult from "./result-card/PerformanceResult";
|
||||
import EnergyUsage from "./result-card/EnergyUsage";
|
||||
import { Bar, Line, Pie } from "react-chartjs-2";
|
||||
import { CompareProduct, useCompareProductDataStore } from "../../../store/builder/store";
|
||||
import { useCompareProductDataStore } from "../../../store/builder/store";
|
||||
// import { CompareProduct, useCompareProductDataStore } from "../../../store/builder/store";
|
||||
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore";
|
||||
|
||||
export interface CompareProduct {
|
||||
productUuid: string;
|
||||
productName: string;
|
||||
simulationData: {
|
||||
roiPercentage: number;
|
||||
netProfit: number;
|
||||
productionCapacity: number;
|
||||
paybackPeriod: number;
|
||||
machineIdleTime: number;
|
||||
machineActiveTime: number;
|
||||
throughputData: number;
|
||||
simulationTime?: number;
|
||||
simulationCost?: number;
|
||||
efficiencyScore?: number;
|
||||
};
|
||||
}
|
||||
const ComparisonResult = () => {
|
||||
const { compareProductsData, setCompareProductsData } = useCompareProductDataStore();
|
||||
const { comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
||||
const { mainProduct } = useMainProduct();
|
||||
const [comparedProducts, setComparedProducts] = useState<[CompareProduct, CompareProduct] | []>([]);
|
||||
const { compareProductsData, setCompareProductsData } = useCompareProductDataStore();
|
||||
const { comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
||||
const { mainProduct } = useMainProduct();
|
||||
const [comparedProducts, setComparedProducts] = useState<[CompareProduct, CompareProduct] | []>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (compareProductsData.length > 0 && mainProduct && comparisonProduct) {
|
||||
const mainProductData = compareProductsData.find(
|
||||
(product) => product.productUuid === mainProduct.productUuid
|
||||
);
|
||||
const comparisonProductData = compareProductsData.find(
|
||||
(product) => product.productUuid === comparisonProduct.productUuid
|
||||
);
|
||||
useEffect(() => {
|
||||
if (compareProductsData.length > 0 && mainProduct && comparisonProduct) {
|
||||
const mainProductData = compareProductsData.find((product) => product.productUuid === mainProduct.productUuid);
|
||||
const comparisonProductData = compareProductsData.find((product) => product.productUuid === comparisonProduct.productUuid);
|
||||
|
||||
if (mainProductData && comparisonProductData) {
|
||||
setComparedProducts([mainProductData, comparisonProductData]);
|
||||
} else {
|
||||
setComparedProducts([]);
|
||||
}
|
||||
} else {
|
||||
setComparedProducts([]);
|
||||
}
|
||||
}, [compareProductsData, mainProduct, comparisonProduct]);
|
||||
if (mainProductData && comparisonProductData) {
|
||||
setComparedProducts([mainProductData, comparisonProductData]);
|
||||
} else {
|
||||
setComparedProducts([]);
|
||||
}
|
||||
} else {
|
||||
setComparedProducts([]);
|
||||
}
|
||||
}, [compareProductsData, mainProduct, comparisonProduct]);
|
||||
|
||||
useEffect(() => {
|
||||
if (comparedProducts.length === 2) {
|
||||
|
||||
}
|
||||
}, [comparedProducts]);
|
||||
useEffect(() => {
|
||||
if (comparedProducts.length === 2) {
|
||||
}
|
||||
}, [comparedProducts]);
|
||||
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: { display: false },
|
||||
legend: { display: false },
|
||||
},
|
||||
scales: {
|
||||
x: { display: false, grid: { display: false } },
|
||||
y: { display: false, grid: { display: false } },
|
||||
},
|
||||
}),
|
||||
[]
|
||||
);
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: { display: false },
|
||||
legend: { display: false },
|
||||
},
|
||||
scales: {
|
||||
x: { display: false, grid: { display: false } },
|
||||
y: { display: false, grid: { display: false } },
|
||||
},
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
// Color palette
|
||||
const purpleDark = "#6a0dad";
|
||||
const purpleLight = "#b19cd9";
|
||||
// Color palette
|
||||
const purpleDark = "#6a0dad";
|
||||
const purpleLight = "#b19cd9";
|
||||
|
||||
const throughputData = {
|
||||
labels: [comparedProducts[0]?.productName, comparedProducts[1]?.productName],
|
||||
datasets: [
|
||||
{
|
||||
label: "Throughput (units/hr)",
|
||||
data: [comparedProducts[0]?.simulationData.throughputData, comparedProducts[1]?.simulationData.throughputData],
|
||||
backgroundColor: [purpleDark, purpleLight],
|
||||
borderColor: [purpleDark, purpleLight],
|
||||
borderWidth: 1,
|
||||
borderRadius: 10, // ✅ Rounded all corners (TypeScript-safe)
|
||||
// borderSkipped: "bottom", // ✅ This is allowed by the Chart.js types
|
||||
},
|
||||
],
|
||||
};
|
||||
const throughputData = {
|
||||
labels: [comparedProducts[0]?.productName, comparedProducts[1]?.productName],
|
||||
datasets: [
|
||||
{
|
||||
label: "Throughput (units/hr)",
|
||||
data: [comparedProducts[0]?.simulationData.throughputData, comparedProducts[1]?.simulationData.throughputData],
|
||||
backgroundColor: [purpleDark, purpleLight],
|
||||
borderColor: [purpleDark, purpleLight],
|
||||
borderWidth: 1,
|
||||
borderRadius: 10, // ✅ Rounded all corners (TypeScript-safe)
|
||||
// borderSkipped: "bottom", // ✅ This is allowed by the Chart.js types
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const cycleTimePieData = {
|
||||
labels: [comparedProducts[0]?.productName, comparedProducts[1]?.productName],
|
||||
datasets: [
|
||||
{
|
||||
label: "Cycle Time (sec)",
|
||||
data: [comparedProducts[0]?.simulationData.machineActiveTime, comparedProducts[1]?.simulationData.machineActiveTime],
|
||||
backgroundColor: [purpleDark, purpleLight],
|
||||
borderColor: "#fff",
|
||||
borderWidth: 2,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const cycleTimePieData = {
|
||||
labels: [comparedProducts[0]?.productName, comparedProducts[1]?.productName],
|
||||
datasets: [
|
||||
{
|
||||
label: "Cycle Time (sec)",
|
||||
data: [comparedProducts[0]?.simulationData.machineActiveTime, comparedProducts[1]?.simulationData.machineActiveTime],
|
||||
backgroundColor: [purpleDark, purpleLight],
|
||||
borderColor: "#fff",
|
||||
borderWidth: 2,
|
||||
},
|
||||
],
|
||||
};
|
||||
const downtimeData = {
|
||||
labels: [comparedProducts[0]?.productName, comparedProducts[1]?.productName],
|
||||
datasets: [
|
||||
{
|
||||
label: "Downtime (mins)",
|
||||
data: [comparedProducts[0]?.simulationData.machineIdleTime, comparedProducts[1]?.simulationData.machineIdleTime],
|
||||
backgroundColor: [purpleDark, purpleLight],
|
||||
borderColor: "#fff",
|
||||
borderWidth: 2,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const downtimeData = {
|
||||
labels: [comparedProducts[0]?.productName, comparedProducts[1]?.productName],
|
||||
datasets: [
|
||||
{
|
||||
label: "Downtime (mins)",
|
||||
data: [comparedProducts[0]?.simulationData.machineIdleTime, comparedProducts[1]?.simulationData.machineIdleTime],
|
||||
backgroundColor: [purpleDark, purpleLight],
|
||||
borderColor: "#fff",
|
||||
borderWidth: 2,
|
||||
},
|
||||
],
|
||||
};
|
||||
const productionCapacityData = {
|
||||
labels: [comparedProducts[0]?.productName, comparedProducts[1]?.productName],
|
||||
datasets: [
|
||||
{
|
||||
label: "Production Capacity (units)",
|
||||
data: [comparedProducts[0]?.simulationData.productionCapacity, comparedProducts[1]?.simulationData.productionCapacity],
|
||||
backgroundColor: [purpleDark, purpleLight],
|
||||
borderColor: [purpleDark, purpleLight],
|
||||
borderWidth: 1,
|
||||
borderRadius: 10,
|
||||
borderSkipped: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const productionCapacityData = {
|
||||
labels: [comparedProducts[0]?.productName, comparedProducts[1]?.productName],
|
||||
datasets: [
|
||||
{
|
||||
label: "Production Capacity (units)",
|
||||
data: [comparedProducts[0]?.simulationData.productionCapacity, comparedProducts[1]?.simulationData.productionCapacity],
|
||||
backgroundColor: [purpleDark, purpleLight],
|
||||
borderColor: [purpleDark, purpleLight],
|
||||
borderWidth: 1,
|
||||
borderRadius: 10,
|
||||
borderSkipped: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
const highestProductivityProduct = (comparedProducts[0]?.simulationData?.productionCapacity ?? 0) > (comparedProducts[1]?.simulationData?.productionCapacity ?? 0) ? comparedProducts[0] : comparedProducts[1];
|
||||
|
||||
const highestProductivityProduct = (comparedProducts[0]?.simulationData?.productionCapacity ?? 0) > (comparedProducts[1]?.simulationData?.productionCapacity ?? 0) ? comparedProducts[0] : comparedProducts[1];
|
||||
const product1CyclePercentage = ((comparedProducts[0]?.simulationData?.machineActiveTime ?? 0) / ((compareProductsData[0]?.simulationData?.machineActiveTime ?? 0) + (compareProductsData[0]?.simulationData?.machineIdleTime ?? 0))) * 100;
|
||||
const product2CyclePercentage = ((comparedProducts[1]?.simulationData?.machineActiveTime ?? 0) / ((compareProductsData[1]?.simulationData?.machineActiveTime ?? 0) + (compareProductsData[1]?.simulationData?.machineIdleTime ?? 0))) * 100;
|
||||
|
||||
const product1CyclePercentage = (comparedProducts[0]?.simulationData?.machineActiveTime ?? 0) /
|
||||
((compareProductsData[0]?.simulationData?.machineActiveTime ?? 0) +
|
||||
(compareProductsData[0]?.simulationData?.machineIdleTime ?? 0)) * 100;
|
||||
const product2CyclePercentage = ((comparedProducts[1]?.simulationData?.machineActiveTime ?? 0) /
|
||||
((compareProductsData[1]?.simulationData?.machineActiveTime ?? 0) +
|
||||
(compareProductsData[1]?.simulationData?.machineIdleTime ?? 0))) * 100;
|
||||
const product1IdlePercentage = ((comparedProducts[0]?.simulationData?.machineIdleTime ?? 0) / ((compareProductsData[0]?.simulationData?.machineActiveTime ?? 0) + (compareProductsData[0]?.simulationData?.machineIdleTime ?? 0))) * 100;
|
||||
const product2IdlePercentage = ((comparedProducts[1]?.simulationData?.machineIdleTime ?? 0) / ((compareProductsData[1]?.simulationData?.machineActiveTime ?? 0) + (compareProductsData[1]?.simulationData?.machineIdleTime ?? 0))) * 100;
|
||||
|
||||
const product1IdlePercentage = (comparedProducts[0]?.simulationData?.machineIdleTime ?? 0) /
|
||||
((compareProductsData[0]?.simulationData?.machineActiveTime ?? 0) +
|
||||
(compareProductsData[0]?.simulationData?.machineIdleTime ?? 0)) * 100;
|
||||
const product2IdlePercentage = ((comparedProducts[1]?.simulationData?.machineIdleTime ?? 0) /
|
||||
((compareProductsData[1]?.simulationData?.machineActiveTime ?? 0) +
|
||||
(compareProductsData[1]?.simulationData?.machineIdleTime ?? 0))) * 100;
|
||||
|
||||
return (
|
||||
<div className="compare-result-container">
|
||||
<div className="header">Performance Comparison</div>
|
||||
<div className="compare-result-wrapper">
|
||||
<EnergyUsage comparedProducts={comparedProducts}/>
|
||||
<div className="throughPutCard-container comparisionCard">
|
||||
<h4>Throughput (units/hr)</h4>
|
||||
<div className="layers-wrapper">
|
||||
<div className="layer-wrapper">
|
||||
<div className="key">{comparedProducts[0]?.productName}</div>
|
||||
<div className="value">{comparedProducts[0]?.simulationData.throughputData}/ hr</div>
|
||||
</div>
|
||||
<div className="layer-wrapper">
|
||||
<div className="key">{comparedProducts[1]?.productName}</div>
|
||||
<div className="value">{comparedProducts[1]?.simulationData.throughputData}/ hr</div>
|
||||
</div>
|
||||
<div className="chart">
|
||||
<Bar data={throughputData} options={options} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="cycle-time-container comparisionCard">
|
||||
<div className="cycle-main">
|
||||
<h4 className="cycle-header">Cycle Time</h4>
|
||||
<div className="layers-wrapper">
|
||||
<div className="layers">
|
||||
<div className="layer-name">{comparedProducts[0]?.productName}</div>
|
||||
<div className="layer-time">{compareProductsData[0]?.simulationData.machineActiveTime} Sec</div>
|
||||
<div className="layer-profit">
|
||||
<span>↑</span>{(100 - product1CyclePercentage).toFixed(2)}%
|
||||
return (
|
||||
<div className="compare-result-container">
|
||||
<div className="header">Performance Comparison</div>
|
||||
<div className="compare-result-wrapper">
|
||||
<EnergyUsage comparedProducts={comparedProducts} />
|
||||
<div className="throughPutCard-container comparisionCard">
|
||||
<h4>Throughput (units/hr)</h4>
|
||||
<div className="layers-wrapper">
|
||||
<div className="layer-wrapper">
|
||||
<div className="key">{comparedProducts[0]?.productName}</div>
|
||||
<div className="value">{comparedProducts[0]?.simulationData.throughputData}/ hr</div>
|
||||
</div>
|
||||
<div className="layer-wrapper">
|
||||
<div className="key">{comparedProducts[1]?.productName}</div>
|
||||
<div className="value">{comparedProducts[1]?.simulationData.throughputData}/ hr</div>
|
||||
</div>
|
||||
<div className="chart">
|
||||
<Bar data={throughputData} options={options} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="layers">
|
||||
<div className="layer-name">{comparedProducts[1]?.productName}</div>
|
||||
<div className="layer-time">{compareProductsData[1]?.simulationData.machineActiveTime} Sec</div>
|
||||
<div className="layer-profit">
|
||||
<span>↑</span>{(100 - product2CyclePercentage).toFixed(2)}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="chart">
|
||||
<Pie data={cycleTimePieData} options={options} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="cycle-time-container comparisionCard">
|
||||
<div className="cycle-main">
|
||||
<div className="cycle-header">Overall Downtime</div>
|
||||
<div className="layers-wrapper">
|
||||
<div className="layers">
|
||||
<div className="layer-name">{comparedProducts[0]?.productName}</div>
|
||||
<div className="layer-time">{compareProductsData[0]?.simulationData.machineIdleTime} Sec</div>
|
||||
<div className="layer-profit">
|
||||
<span>↑</span>{(100 - product1IdlePercentage).toFixed(2)}%
|
||||
<div className="cycle-time-container comparisionCard">
|
||||
<div className="cycle-main">
|
||||
<h4 className="cycle-header">Cycle Time</h4>
|
||||
<div className="layers-wrapper">
|
||||
<div className="layers">
|
||||
<div className="layer-name">{comparedProducts[0]?.productName}</div>
|
||||
<div className="layer-time">{compareProductsData[0]?.simulationData.machineActiveTime} Sec</div>
|
||||
<div className="layer-profit">
|
||||
<span>↑</span>
|
||||
{(100 - product1CyclePercentage).toFixed(2)}%
|
||||
</div>
|
||||
</div>
|
||||
<div className="layers">
|
||||
<div className="layer-name">{comparedProducts[1]?.productName}</div>
|
||||
<div className="layer-time">{compareProductsData[1]?.simulationData.machineActiveTime} Sec</div>
|
||||
<div className="layer-profit">
|
||||
<span>↑</span>
|
||||
{(100 - product2CyclePercentage).toFixed(2)}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="chart">
|
||||
<Pie data={cycleTimePieData} options={options} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="layers">
|
||||
<div className="layer-name">{comparedProducts[1]?.productName}</div>
|
||||
<div className="layer-time">{compareProductsData[1]?.simulationData.machineIdleTime} Sec</div>
|
||||
<div className="layer-profit">
|
||||
<span>↑</span>{(100 - product2IdlePercentage).toFixed(2)}%
|
||||
|
||||
<div className="cycle-time-container comparisionCard">
|
||||
<div className="cycle-main">
|
||||
<div className="cycle-header">Overall Downtime</div>
|
||||
<div className="layers-wrapper">
|
||||
<div className="layers">
|
||||
<div className="layer-name">{comparedProducts[0]?.productName}</div>
|
||||
<div className="layer-time">{compareProductsData[0]?.simulationData.machineIdleTime} Sec</div>
|
||||
<div className="layer-profit">
|
||||
<span>↑</span>
|
||||
{(100 - product1IdlePercentage).toFixed(2)}%
|
||||
</div>
|
||||
</div>
|
||||
<div className="layers">
|
||||
<div className="layer-name">{comparedProducts[1]?.productName}</div>
|
||||
<div className="layer-time">{compareProductsData[1]?.simulationData.machineIdleTime} Sec</div>
|
||||
<div className="layer-profit">
|
||||
<span>↑</span>
|
||||
{(100 - product2IdlePercentage).toFixed(2)}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="chart">
|
||||
<Pie data={downtimeData} options={options} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="chart">
|
||||
<Pie data={downtimeData} options={options} />
|
||||
</div>
|
||||
</div>
|
||||
{/*
|
||||
{/*
|
||||
<div className="overallDowntime-container comparisionCard">
|
||||
<h4 className="overallDowntime-header">Overall Downtime</h4>
|
||||
<div className="totalDownTime-wrapper">
|
||||
@@ -220,24 +226,24 @@ const ComparisonResult = () => {
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="overallScrapRate comparisionCard">
|
||||
<h4 className="overallScrapRate-header">Production Capacity</h4>
|
||||
<div className="overallScrapRate-wrapper">
|
||||
<div className="overallScrapRate-value">
|
||||
<div className="overallScrapRate-label">{highestProductivityProduct?.productName}</div>
|
||||
<div className="overallScrapRate-key">Total product produced</div>
|
||||
<div className="overallScrapRateKey-value">{highestProductivityProduct?.simulationData.productionCapacity}</div>
|
||||
</div>
|
||||
<div className="chart">
|
||||
<Bar data={productionCapacityData} options={options} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="overallScrapRate comparisionCard">
|
||||
<h4 className="overallScrapRate-header">Production Capacity</h4>
|
||||
<div className="overallScrapRate-wrapper">
|
||||
<div className="overallScrapRate-value">
|
||||
<div className="overallScrapRate-label">{highestProductivityProduct?.productName}</div>
|
||||
<div className="overallScrapRate-key">Total product produced</div>
|
||||
<div className="overallScrapRateKey-value">{highestProductivityProduct?.simulationData.productionCapacity}</div>
|
||||
</div>
|
||||
<div className="chart">
|
||||
<Bar data={productionCapacityData} options={options} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{ comparedProducts.length === 2 &&<PerformanceResult comparedProducts={comparedProducts}/>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
{comparedProducts.length === 2 && <PerformanceResult comparedProducts={comparedProducts} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ComparisonResult;
|
||||
|
||||
Reference in New Issue
Block a user