diff --git a/frontend/src/components/ModelManage/EvaluationTab.tsx b/frontend/src/components/ModelManage/EvaluationTab.tsx index 89e5311..9dd0639 100644 --- a/frontend/src/components/ModelManage/EvaluationTab.tsx +++ b/frontend/src/components/ModelManage/EvaluationTab.tsx @@ -1,11 +1,11 @@ import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; -import { useState } from 'react'; import useProjectModelsQuery from '@/queries/models/useProjectModelsQuery'; import useModelReportsQuery from '@/queries/models/useModelReportsQuery'; import useModelResultsQuery from '@/queries/models/useModelResultsQuery'; import ModelBarChart from './ModelBarChart'; import ModelLineChart from './ModelLineChart'; +import { useState } from 'react'; interface EvaluationTabProps { projectId: number | null; @@ -13,7 +13,6 @@ interface EvaluationTabProps { export default function EvaluationTab({ projectId }: EvaluationTabProps) { const [selectedModel, setSelectedModel] = useState(null); - const { data: models } = useProjectModelsQuery(projectId ?? 0); return ( @@ -70,47 +69,62 @@ function ModelEvaluation({ projectId, selectedModel }: ModelEvaluationProps) { const { data: reportData } = useModelReportsQuery(projectId, selectedModel); const { data: resultData } = useModelResultsQuery(selectedModel); - if (!reportData || !resultData) { - return null; - } + if (!reportData || !resultData) return null; + + const trainingInfoRow = ( +
+
+ Epochs +

{resultData[0]?.epochs}

+
+
+ Batch Size +

{resultData[0]?.batch}

+
+
+ Learning Rate (Start) +

{resultData[0]?.lr0}

+
+
+ Learning Rate (End) +

{resultData[0]?.lrf}

+
+
+ Optimizer +

{resultData[0]?.optimizer}

+
+
+ ); return ( -
-
- +
+ {trainingInfoRow} {/* 학습 정보 표시 */} +
+ {' '} + {/* grid와 높이 설정 */} +
+ {' '} + {/* 차트의 높이를 100%로 맞춤 */} + +
+
+ {' '} + {/* 차트의 높이를 100%로 맞춤 */} + +
- -
- ({ - epoch: report.epoch.toString(), - boxLoss: report.boxLoss, - classLoss: report.clsLoss, - dflLoss: report.dflLoss, - fitness: report.fitness, - }))} - /> -
- - {/*
- -
*/}
); } - -// function LabelingPreview() { -// return ( -//
-//

레이블링 프리뷰

-//
-// ); -// } diff --git a/frontend/src/components/ModelManage/InputWithLabel.tsx b/frontend/src/components/ModelManage/InputWithLabel.tsx index 48bfe9b..c01f878 100644 --- a/frontend/src/components/ModelManage/InputWithLabel.tsx +++ b/frontend/src/components/ModelManage/InputWithLabel.tsx @@ -6,9 +6,10 @@ interface InputWithLabelProps { placeholder: string; value: number; onChange: (e: React.ChangeEvent) => void; + disabled?: boolean; } -export default function InputWithLabel({ label, id, placeholder, value, onChange }: InputWithLabelProps) { +export default function InputWithLabel({ label, id, placeholder, value, disabled, onChange }: InputWithLabelProps) { return (
@@ -18,6 +19,7 @@ export default function InputWithLabel({ label, id, placeholder, value, onChange placeholder={placeholder} value={value} onChange={onChange} + disabled={disabled} />
); diff --git a/frontend/src/components/ModelManage/ModelBarChart.tsx b/frontend/src/components/ModelManage/ModelBarChart.tsx index abbae01..8e95802 100644 --- a/frontend/src/components/ModelManage/ModelBarChart.tsx +++ b/frontend/src/components/ModelManage/ModelBarChart.tsx @@ -1,9 +1,8 @@ 'use client'; -import { TrendingUp } from 'lucide-react'; import { Bar, BarChart, CartesianGrid, Rectangle, XAxis } from 'recharts'; -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart'; interface MetricData { @@ -14,10 +13,9 @@ interface MetricData { interface ModelBarChartProps { data: MetricData[]; + className?: string; } -export const description = 'A bar chart with an active bar'; - const chartConfig = { precision: { label: 'Precision', @@ -41,9 +39,9 @@ const chartConfig = { }, } satisfies ChartConfig; -export default function ModelBarChart({ data }: ModelBarChartProps) { +export default function ModelBarChart({ data, className }: ModelBarChartProps) { return ( - + Model Metrics Performance metrics of the model @@ -86,12 +84,6 @@ export default function ModelBarChart({ data }: ModelBarChartProps) { - -
- Model metrics are trending well -
-
Showing current performance metrics
-
); } diff --git a/frontend/src/components/ModelManage/ModelLineChart.tsx b/frontend/src/components/ModelManage/ModelLineChart.tsx index bd21ea8..cae6dd6 100644 --- a/frontend/src/components/ModelManage/ModelLineChart.tsx +++ b/frontend/src/components/ModelManage/ModelLineChart.tsx @@ -3,20 +3,11 @@ import { CartesianGrid, Line, LineChart, XAxis, YAxis, Tooltip, Legend } from 'recharts'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { ChartConfig, ChartContainer } from '@/components/ui/chart'; - -interface MetricData { - epoch: string; - boxLoss?: number; - classLoss?: number; - dflLoss?: number; - fitness?: number; -} +import { ReportResponse } from '@/types'; interface ModelLineChartProps { - data: MetricData[]; - currentEpoch?: number; - totalEpochs?: number; - remainingTime?: number; + data: ReportResponse[]; + className?: string; } const chartConfig = { @@ -38,8 +29,11 @@ const chartConfig = { }, } satisfies ChartConfig; -export default function ModelLineChart({ data, currentEpoch, totalEpochs, remainingTime }: ModelLineChartProps) { - const emptyData = Array.from({ length: totalEpochs || 0 }, (_, i) => ({ +export default function ModelLineChart({ data, className }: ModelLineChartProps) { + const latestData = data.length > 0 ? data[data.length - 1] : undefined; + + const totalEpochs = latestData?.totalEpochs || 0; + const emptyData = Array.from({ length: totalEpochs }, (_, i) => ({ epoch: (i + 1).toString(), boxLoss: null, classLoss: null, @@ -53,16 +47,16 @@ export default function ModelLineChart({ data, currentEpoch, totalEpochs, remain })); return ( - + Model Training Metrics - {currentEpoch !== undefined && totalEpochs !== undefined && remainingTime !== undefined && ( + {latestData && latestData.totalEpochs !== Number(latestData.epoch) && (
-

현재 에포크: {currentEpoch}

-

총 에포크: {totalEpochs}

-

예상 남은시간: {remainingTime}

+

현재 에포크: {latestData.epoch}

+

총 에포크: {latestData.totalEpochs}

+

예상 남은시간: {latestData.leftSecond}초

)} diff --git a/frontend/src/components/ModelManage/SelectWithLabel.tsx b/frontend/src/components/ModelManage/SelectWithLabel.tsx index da860f6..b6c7ad8 100644 --- a/frontend/src/components/ModelManage/SelectWithLabel.tsx +++ b/frontend/src/components/ModelManage/SelectWithLabel.tsx @@ -12,16 +12,27 @@ interface SelectWithLabelProps { options: SelectWithLabelOption[]; placeholder: string; value: string; + disabled?: boolean; + onChange: (value: string) => void; } -export default function SelectWithLabel({ label, id, options, placeholder, value, onChange }: SelectWithLabelProps) { +export default function SelectWithLabel({ + label, + id, + options, + placeholder, + value, + disabled, + onChange, +}: SelectWithLabelProps) { return (