snp-sync-batch/frontend/src/components/BarChart.tsx
HYOJIN 744cc02f36 feat: snp-sync-batch 프로젝트 초기 설정
mda-snp-batch 기반으로 snp-sync-batch 프로젝트 생성
- 프론트엔드: Thymeleaf → React + TypeScript + Vite + Tailwind CSS 전환
- 컨텍스트: /snp-sync, 포트 8051
- 재수집(Recollection) 관련 코드 제거
- displayName → job_schedule.description 기반으로 전환
- 누락 API 추가 (statistics, jobs/detail, executions/recent)
- 실행 이력 조회 속도 개선 (JDBC 경량 쿼리)
- 스케줄 CRUD API 메서드 매핑 수정 (PUT/DELETE)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:33:31 +09:00

75 lines
2.1 KiB
TypeScript

interface BarValue {
color: string;
value: number;
}
interface BarData {
label: string;
values: BarValue[];
}
interface Props {
data: BarData[];
height?: number;
}
export default function BarChart({ data, height = 200 }: Props) {
const maxTotal = Math.max(...data.map((d) => d.values.reduce((sum, v) => sum + v.value, 0)), 1);
return (
<div className="w-full">
<div className="flex items-end gap-1" style={{ height }}>
{data.map((bar, i) => {
const total = bar.values.reduce((sum, v) => sum + v.value, 0);
const ratio = total / maxTotal;
return (
<div key={i} className="flex-1 flex flex-col justify-end h-full min-w-0">
<div
className="w-full rounded-t overflow-hidden"
style={{ height: `${ratio * 100}%` }}
title={bar.values.map((v) => `${v.color}: ${v.value}`).join(', ')}
>
{bar.values
.filter((v) => v.value > 0)
.map((v, j) => {
const segmentRatio = total > 0 ? (v.value / total) * 100 : 0;
return (
<div
key={j}
className={colorToClass(v.color)}
style={{ height: `${segmentRatio}%` }}
/>
);
})}
</div>
</div>
);
})}
</div>
<div className="flex gap-1 mt-1">
{data.map((bar, i) => (
<div key={i} className="flex-1 min-w-0">
<p className="text-[10px] text-gray-500 text-center truncate" title={bar.label}>
{bar.label}
</p>
</div>
))}
</div>
</div>
);
}
function colorToClass(color: string): string {
const map: Record<string, string> = {
green: 'bg-green-500',
red: 'bg-red-500',
gray: 'bg-gray-400',
blue: 'bg-blue-500',
yellow: 'bg-yellow-500',
orange: 'bg-orange-500',
indigo: 'bg-indigo-500',
};
return map[color] ?? color;
}