143 lines
3.5 KiB
TypeScript
143 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
Chart as ChartJS,
|
|
CategoryScale,
|
|
LinearScale,
|
|
BarElement,
|
|
Title,
|
|
Tooltip,
|
|
Legend,
|
|
type ChartOptions,
|
|
} from "chart.js";
|
|
import { Bar } from "react-chartjs-2";
|
|
import { Card, CardHeader, CardTitle, CardContent } from "@common/business_components/ui/chart/lib/card";
|
|
import { Button } from "@common/components";
|
|
|
|
// ChartJS 컴포넌트 등록
|
|
ChartJS.register(
|
|
CategoryScale,
|
|
LinearScale,
|
|
BarElement,
|
|
Title,
|
|
Tooltip,
|
|
Legend
|
|
);
|
|
|
|
export default function TestPage() {
|
|
// 차트 데이터
|
|
const labels = ["한강", "낙동강", "영산강", "금강"];
|
|
|
|
const datasets = [
|
|
{
|
|
label: '20-25년',
|
|
data: [3859, 1066, 1929, 2828],
|
|
backgroundColor: '#3B82F6', // 파란색
|
|
borderRadius: 4,
|
|
},
|
|
{
|
|
label: '25년-30년',
|
|
data: [3153, 1420, 1204, 2877],
|
|
backgroundColor: '#EF4444', // 빨간색
|
|
borderRadius: 4,
|
|
},
|
|
{
|
|
label: '30년이상',
|
|
data: [9404, 1835, 1821, 8115],
|
|
backgroundColor: '#F87171', // 연한 빨간색/분홍색
|
|
borderRadius: 4,
|
|
},
|
|
];
|
|
|
|
// 각 지역별 총 길이 계산
|
|
const totalLengths = [44251, 33786, 11888, 14878];
|
|
|
|
// 차트 옵션 설정
|
|
const options: ChartOptions<"bar"> = {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
scales: {
|
|
x: {
|
|
grid: {
|
|
display: true,
|
|
},
|
|
},
|
|
y: {
|
|
beginAtZero: true,
|
|
min: 0,
|
|
max: 10000,
|
|
ticks: {
|
|
stepSize: 2000,
|
|
callback: function(value) {
|
|
return value + 'km';
|
|
}
|
|
},
|
|
grid: {
|
|
color: 'rgba(200, 200, 200, 0.3)',
|
|
}
|
|
}
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
position: 'top',
|
|
align: 'start',
|
|
labels: {
|
|
boxWidth: 15,
|
|
padding: 15,
|
|
usePointStyle: false,
|
|
},
|
|
},
|
|
tooltip: {
|
|
callbacks: {
|
|
label: function(context) {
|
|
return `${context.dataset.label}: ${context.parsed.y}km`;
|
|
}
|
|
}
|
|
},
|
|
},
|
|
// 총 길이 데이터 표시를 위한 애니메이션 후 함수 설정
|
|
animation: {
|
|
onComplete: function(animation) {
|
|
const chart = animation.chart;
|
|
const ctx = chart.ctx;
|
|
|
|
// 각 데이터셋의 마지막 데이터셋의 인덱스
|
|
const lastDatasetIndex = datasets.length - 1;
|
|
|
|
// 텍스트 스타일 설정
|
|
ctx.font = '11px Arial';
|
|
ctx.fillStyle = '#333';
|
|
ctx.textAlign = 'center';
|
|
|
|
// 각 지역별로 총 길이 표시
|
|
labels.forEach((_, i) => {
|
|
const xPos = chart.scales.x ? chart.scales.x.getPixelForTick(i) : 0;
|
|
const yPos = chart.chartArea.top; // 차트 영역 최상단 위에 표시
|
|
|
|
// 막대 위에 총 길이 텍스트 표시
|
|
if (totalLengths[i]) ctx.fillText(`총 ${totalLengths[i].toLocaleString()}km`, xPos, yPos);
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
const data = {
|
|
labels,
|
|
datasets,
|
|
};
|
|
|
|
return (
|
|
<Card className="w-full">
|
|
<CardHeader className="flex flex-row items-center justify-between pb-2">
|
|
<CardTitle className="text-base">노후하수관로현황</CardTitle>
|
|
<Button size="sm">더보기</Button>
|
|
</CardHeader>
|
|
<CardContent className="pb-4">
|
|
{/* 너비 400px, 높이 150px로 조정 */}
|
|
<div className="w-[400px] h-[150px] mx-auto">
|
|
<Bar options={options} data={data} />
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
} |