233 lines
5.9 KiB
TypeScript
233 lines
5.9 KiB
TypeScript
"use client";
|
|
/**
|
|
* 수계별 유입ㆍ방류수질 분석
|
|
*/
|
|
import React, { useState } from 'react';
|
|
import { Line } from 'react-chartjs-2';
|
|
import BasinSelect from "./basIn-select";
|
|
import {
|
|
Chart as ChartJS,
|
|
CategoryScale,
|
|
LinearScale,
|
|
PointElement,
|
|
LineElement,
|
|
Title,
|
|
Tooltip,
|
|
Legend,
|
|
type ChartOptions,
|
|
} from 'chart.js';
|
|
|
|
// Chart.js 등록
|
|
ChartJS.register(
|
|
CategoryScale,
|
|
LinearScale,
|
|
PointElement,
|
|
LineElement,
|
|
Title,
|
|
Tooltip,
|
|
Legend
|
|
);
|
|
|
|
type WaterQualityType = 'BOD' | 'TOC' | 'SS' | 'TP' | 'TN';
|
|
|
|
interface ChartData {
|
|
labels: string[];
|
|
inflowData: number[];
|
|
inflowAverage: number[];
|
|
effluentData: number[];
|
|
effluentAverage: number[];
|
|
}
|
|
|
|
const FoWqltInflEffl: React.FC = () => {
|
|
const [selectedBasin, setSelectedBasin] = useState<string>("한강");
|
|
const [selectedTab, setSelectedTab] = useState<WaterQualityType>('BOD');
|
|
|
|
// 데이터 (실제로는 API에서 가져올 데이터)
|
|
const bodData: ChartData = {
|
|
labels: ['2020', '2021', '2022', '2023', '2024'],
|
|
inflowData: [2255.6, 2282.2, 2304.3, 5156.6, 4620.4],
|
|
inflowAverage: [2255.6, 2282.2, 2304.3, 2304.3, 2304.3],
|
|
effluentData: [55, 47.5, 52, 79.7, 83.9],
|
|
effluentAverage: [55, 47.5, 52, 52, 52],
|
|
};
|
|
|
|
const tabs: WaterQualityType[] = ['BOD', 'TOC', 'SS', 'TP', 'TN'];
|
|
|
|
// 차트 공통 옵션
|
|
// const getChartOptions = (yAxisLabel: string): ChartOptions<'line'> => ({
|
|
const getChartOptions = (): ChartOptions<'line'> => ({
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
interaction: {
|
|
mode: 'index',
|
|
intersect: false,
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
display: true,
|
|
position: 'bottom',
|
|
labels: {
|
|
usePointStyle: true,
|
|
boxWidth: 6,
|
|
color: '#000',
|
|
font: {
|
|
size: 8,
|
|
},
|
|
},
|
|
},
|
|
tooltip: {
|
|
enabled: true,
|
|
titleFont: { size: 10 },
|
|
bodyFont: { size: 10 },
|
|
},
|
|
},
|
|
scales: {
|
|
x: {
|
|
grid: {
|
|
color: 'rgba(255, 255, 255, 0.1)',
|
|
tickLength: 4, // 눈금 길이 축소
|
|
},
|
|
ticks: {
|
|
color: '#000',
|
|
font: {
|
|
size: 8, // 폰트 크기 축소
|
|
},
|
|
padding: 0,
|
|
},
|
|
},
|
|
y: {
|
|
grid: {
|
|
color: 'rgba(255, 255, 255, 0.1)',
|
|
},
|
|
ticks: {
|
|
color: '#000',
|
|
font: {
|
|
size: 8, // 폰트 크기 축소
|
|
},
|
|
maxTicksLimit: 4, // 눈금 개수 제한
|
|
padding: 2,
|
|
},
|
|
title: {
|
|
display: false,
|
|
},
|
|
},
|
|
},
|
|
layout: {
|
|
padding: {
|
|
top: 5,
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 5
|
|
}
|
|
}
|
|
});
|
|
|
|
// 유입 데이터 차트 설정
|
|
const inflowChartData = {
|
|
labels: bodData.labels,
|
|
datasets: [
|
|
{
|
|
label: '유입BOD (mg/L)',
|
|
data: bodData.inflowData,
|
|
borderColor: '#00D4FF',
|
|
backgroundColor: '#00D4FF',
|
|
borderWidth: 1,
|
|
pointRadius: 2,
|
|
pointHoverRadius: 4,
|
|
tension: 0.4,
|
|
},
|
|
{
|
|
label: '유입 평균 (mg/L)',
|
|
data: bodData.inflowAverage,
|
|
borderColor: '#FF1493',
|
|
backgroundColor: '#FF1493',
|
|
borderWidth: 1,
|
|
borderDash: [10, 5],
|
|
pointRadius: 2,
|
|
pointHoverRadius: 4,
|
|
tension: 0,
|
|
},
|
|
],
|
|
};
|
|
|
|
// 발류 데이터 차트 설정
|
|
const effluentChartData = {
|
|
labels: bodData.labels,
|
|
datasets: [
|
|
{
|
|
label: '발류BOD (mg/L)',
|
|
data: bodData.effluentData,
|
|
borderColor: '#00FF88',
|
|
backgroundColor: '#00FF88',
|
|
borderWidth: 1,
|
|
pointRadius: 2,
|
|
pointHoverRadius: 4,
|
|
tension: 0.4,
|
|
},
|
|
{
|
|
label: '발류 평균 (mg/L)',
|
|
data: bodData.effluentAverage,
|
|
borderColor: '#FFB800',
|
|
backgroundColor: '#FFB800',
|
|
borderWidth: 1,
|
|
borderDash: [10, 5],
|
|
pointRadius: 1,
|
|
pointHoverRadius: 4,
|
|
tension: 0,
|
|
},
|
|
],
|
|
};
|
|
|
|
return (
|
|
<div className="card card-border">
|
|
<div className="card-header text-foreground">
|
|
<h3 className="text-2xl font-medium">수계별 유입ㆍ방류수질 분석</h3>
|
|
<BasinSelect selectedBasin={selectedBasin} onValueChange={setSelectedBasin} />
|
|
</div>
|
|
<div className="h-60">
|
|
<div style={{ padding: '4px', height: '100%', display: 'flex', flexDirection: 'column' }}>
|
|
{/* 탭 메뉴 */}
|
|
<div style={{ display: 'flex', gap: '20px', borderBottom: '1px solid #000000', flexShrink: 0 }}>
|
|
{tabs.map((tab) => (
|
|
<button
|
|
key={tab}
|
|
onClick={() => setSelectedTab(tab)}
|
|
style={{
|
|
background: 'none',
|
|
border: 'none',
|
|
color: selectedTab === tab ? '#00D4FF' : '#6b7c93',
|
|
fontSize: '8px',
|
|
fontWeight: selectedTab === tab ? 'bold' : 'normal',
|
|
cursor: 'pointer',
|
|
borderBottom: selectedTab === tab ? '3px solid #00D4FF' : 'none',
|
|
transition: 'all 0.3s',
|
|
}}
|
|
>
|
|
{tab}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
{/* 차트 영역 */}
|
|
<div style={{ display: 'flex', flexDirection: 'column',flex: 1, minHeight: 0 }}>
|
|
{/* 유입 차트 */}
|
|
<div style={{ flex: 1, position: 'relative', minHeight: 0 }}>
|
|
{/* <Line data={inflowChartData} options={getChartOptions('mg/L')} /> */}
|
|
<Line data={inflowChartData} options={getChartOptions()} />
|
|
</div>
|
|
|
|
{/* 발류 차트 */}
|
|
<div style={{ flex: 1, position: 'relative', minHeight: 0 }}>
|
|
<Line data={effluentChartData} options={getChartOptions()} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
);
|
|
};
|
|
|
|
export default FoWqltInflEffl;
|