'use client' import { useState } from 'react' import { Card, CardContent } from "@/components/ui/card" import { Area, ComposedChart, ResponsiveContainer, XAxis, YAxis, ReferenceLine, Customized, } from 'recharts' // 샘플 데이터 const SAMPLE_DATA = { cow: { name: '7805', score: 0.85 }, farm: { name: '농가', score: 0.53 }, region: { name: '보은군', score: 0.21 }, } // 정규분포 히스토그램 데이터 const histogramData = [ { midPoint: -2.5, percent: 2.3 }, { midPoint: -2.0, percent: 4.4 }, { midPoint: -1.5, percent: 9.2 }, { midPoint: -1.0, percent: 15.0 }, { midPoint: -0.5, percent: 19.1 }, { midPoint: 0.0, percent: 19.1 }, { midPoint: 0.5, percent: 15.0 }, { midPoint: 1.0, percent: 9.2 }, { midPoint: 1.5, percent: 4.4 }, { midPoint: 2.0, percent: 2.3 }, ] export default function ChartOptionsDemo() { const [selectedOption, setSelectedOption] = useState('A') const cowScore = SAMPLE_DATA.cow.score const farmScore = SAMPLE_DATA.farm.score const regionScore = SAMPLE_DATA.region.score const farmDiff = cowScore - farmScore const regionDiff = cowScore - regionScore return (

차트 대비 표시 옵션 데모

개체: +{cowScore.toFixed(2)} | 농가: +{farmScore.toFixed(2)} | 보은군: +{regionScore.toFixed(2)}

{/* 옵션 선택 탭 */}
{['A', 'B', 'C', 'D', 'E'].map((opt) => ( ))}
{/* 옵션 A: 차트 내에 대비값 항상 표시 */} {selectedOption === 'A' && (

옵션 A: 차트 내에 대비값 항상 표시

개체 선 옆에 농가/보은군 대비값을 직접 표시

{ const { xAxisMap, yAxisMap } = props if (!xAxisMap || !yAxisMap) return null const xAxis = Object.values(xAxisMap)[0] as any const yAxis = Object.values(yAxisMap)[0] as any if (!xAxis || !yAxis) return null const chartX = xAxis.x const chartWidth = xAxis.width const chartTop = yAxis.y const [domainMin, domainMax] = xAxis.domain || [-2.5, 2.5] const domainRange = domainMax - domainMin const sigmaToX = (sigma: number) => chartX + ((sigma - domainMin) / domainRange) * chartWidth const cowX = sigmaToX(cowScore) return ( {/* 개체 라벨 + 대비값 */} 개체 +{cowScore.toFixed(2)} 농가+{farmDiff.toFixed(2)} | 보은군+{regionDiff.toFixed(2)} ) }} />
)} {/* 옵션 B: 선 사이 영역 색으로 채우기 */} {selectedOption === 'B' && (

옵션 B: 선 사이 영역 색으로 채우기

개체~농가, 개체~보은군 사이를 색으로 강조

{ const { xAxisMap, yAxisMap } = props if (!xAxisMap || !yAxisMap) return null const xAxis = Object.values(xAxisMap)[0] as any const yAxis = Object.values(yAxisMap)[0] as any if (!xAxis || !yAxis) return null const chartX = xAxis.x const chartWidth = xAxis.width const chartTop = yAxis.y const chartHeight = yAxis.height const [domainMin, domainMax] = xAxis.domain || [-2.5, 2.5] const domainRange = domainMax - domainMin const sigmaToX = (sigma: number) => chartX + ((sigma - domainMin) / domainRange) * chartWidth const cowX = sigmaToX(cowScore) const farmX = sigmaToX(farmScore) const regionX = sigmaToX(regionScore) return ( {/* 개체~농가 영역 (주황색) */} {/* 농가~보은군 영역 (파란색) */} {/* 대비값 라벨 */} +{farmDiff.toFixed(2)} +{(farmScore - regionScore).toFixed(2)} ) }} />
)} {/* 옵션 C: 개체 배지에 대비값 추가 */} {selectedOption === 'C' && (

옵션 C: 개체 배지에 대비값 추가

개체 배지를 확장해서 대비값 포함

{ const { xAxisMap, yAxisMap } = props if (!xAxisMap || !yAxisMap) return null const xAxis = Object.values(xAxisMap)[0] as any const yAxis = Object.values(yAxisMap)[0] as any if (!xAxis || !yAxis) return null const chartX = xAxis.x const chartWidth = xAxis.width const chartTop = yAxis.y const [domainMin, domainMax] = xAxis.domain || [-2.5, 2.5] const domainRange = domainMax - domainMin const sigmaToX = (sigma: number) => chartX + ((sigma - domainMin) / domainRange) * chartWidth const cowX = sigmaToX(cowScore) const farmX = sigmaToX(farmScore) const regionX = sigmaToX(regionScore) return ( {/* 보은군 배지 */} 보은군 +{regionScore.toFixed(2)} {/* 농가 배지 */} 농가 +{farmScore.toFixed(2)} {/* 개체 배지 (확장) */} 개체 +{cowScore.toFixed(2)} 농가 대비 +{farmDiff.toFixed(2)} | 보은군 대비 +{regionDiff.toFixed(2)} ) }} />
)} {/* 옵션 D: 차트 모서리에 오버레이 박스 */} {selectedOption === 'D' && (

옵션 D: 차트 모서리에 오버레이 박스

차트 우측 상단에 대비값 요약 박스

{/* 오버레이 박스 */}
개체 대비
농가 +{farmDiff.toFixed(2)}
보은군 +{regionDiff.toFixed(2)}
{ const { xAxisMap, yAxisMap } = props if (!xAxisMap || !yAxisMap) return null const xAxis = Object.values(xAxisMap)[0] as any const yAxis = Object.values(yAxisMap)[0] as any if (!xAxis || !yAxis) return null const chartX = xAxis.x const chartWidth = xAxis.width const chartTop = yAxis.y const [domainMin, domainMax] = xAxis.domain || [-2.5, 2.5] const domainRange = domainMax - domainMin const sigmaToX = (sigma: number) => chartX + ((sigma - domainMin) / domainRange) * chartWidth const cowX = sigmaToX(cowScore) const farmX = sigmaToX(farmScore) const regionX = sigmaToX(regionScore) return ( {/* 심플 배지들 */} 보은군 농가 개체 ) }} />
)} {/* 옵션 E: 화살표로 차이 표시 */} {selectedOption === 'E' && (

옵션 E: 화살표로 차이 표시

개체에서 농가/보은군으로 화살표 + 차이값

{ const { xAxisMap, yAxisMap } = props if (!xAxisMap || !yAxisMap) return null const xAxis = Object.values(xAxisMap)[0] as any const yAxis = Object.values(yAxisMap)[0] as any if (!xAxis || !yAxis) return null const chartX = xAxis.x const chartWidth = xAxis.width const chartTop = yAxis.y const chartHeight = yAxis.height const [domainMin, domainMax] = xAxis.domain || [-2.5, 2.5] const domainRange = domainMax - domainMin const sigmaToX = (sigma: number) => chartX + ((sigma - domainMin) / domainRange) * chartWidth const cowX = sigmaToX(cowScore) const farmX = sigmaToX(farmScore) const regionX = sigmaToX(regionScore) const arrowY1 = chartTop + chartHeight * 0.3 const arrowY2 = chartTop + chartHeight * 0.5 return ( {/* 개체 → 농가 화살표 */} +{farmDiff.toFixed(2)} {/* 개체 → 보은군 화살표 */} +{regionDiff.toFixed(2)} {/* 배지 */} 개체 ) }} />
)} {/* 옵션 설명 */}

옵션 비교

A: 개체 배지 옆에 대비값 직접 표시 - 간단하지만 정보 밀집
B: 영역 색칠로 거리감 강조 - 시각적으로 차이가 명확
C: 개체 배지 확장 - 배지에 모든 정보 포함
D: 오버레이 박스 - 차트 방해 없이 정보 제공
E: 화살표 - 방향성과 차이 동시 표현
) }