/**
* ChartPanel.tsx — 차트 패널 및 AI 분석 패널 컴포넌트
*
* 역할:
* - ChartPanel: 종목 캔들 차트 표시 (TradingChart 래퍼), 일/주/월봉 기간 전환
* - AiAnalysisPanel: 선택 종목의 AI 투자 분석 텍스트 표시
*
* 최적화:
* - React.memo + 커스텀 비교 함수로 livePrice 변경 시 리렌더 방지
* (livePrice는 TradingChart 내부에서 ref 기반으로 처리)
* - 차트 로딩 중에도 기존 차트를 유지하여 깜빡임 방지
*/
import React from 'react'
import { Brain, RefreshCw } from 'lucide-react'
import { TradingChart } from './TradingChart'
import { formatTime } from '../utils/formatUtils'
/** ChartPanel Props 정의 */
interface ChartPanelProps {
/** 캔들 차트 데이터 배열 (null이면 데이터 없음 표시) */
chartData: any[] | null | undefined
/** 차트 로딩 상태 (오버레이 스피너 표시 여부) */
chartLoading: boolean
/** 현재 선택된 종목 코드 */
selectedStock: string
/** 차트 기간 (D: 일봉, W: 주봉, M: 월봉) */
chartPeriod: 'D' | 'W' | 'M'
/** 기간 변경 콜백 */
onPeriodChange: (period: 'D' | 'W' | 'M') => void
/** 차트 헤더에 표시할 종목명 */
stockName: string
/** 실시간 현재가 (TradingChart에서 ref 기반 처리) */
livePrice?: number
}
/**
* ChartPanel — 종목 캔들 차트 패널
*
* React.memo 커스텀 비교 함수:
* - livePrice 변경은 무시 (TradingChart가 ref 기반 500ms polling으로 직접 처리)
* - chartData, chartLoading, selectedStock, chartPeriod 등 변경 시에만 리렌더
*/
const ChartPanel = React.memo(({
chartData,
chartLoading,
selectedStock,
chartPeriod,
onPeriodChange,
stockName,
livePrice,
}: ChartPanelProps) => {
return (
)
}, (prev, next) => {
// livePrice 변경은 TradingChart 내부에서 ref 기반 처리 — ChartPanel 리렌더 불필요
if (prev.chartData !== next.chartData) return false
if (prev.chartLoading !== next.chartLoading) return false
if (prev.selectedStock !== next.selectedStock) return false
if (prev.chartPeriod !== next.chartPeriod) return false
if (prev.stockName !== next.stockName) return false
if (prev.onPeriodChange !== next.onPeriodChange) return false
// livePrice 변경은 무시 (TradingChart가 ref로 직접 처리)
return true
})
ChartPanel.displayName = 'ChartPanel'
/**
* AiAnalysisPanel — AI 투자 분석 결과 표시 패널
*
* 선택된 종목의 기술적 지표, 추천 방향, AI 분석 근거를 텍스트로 표시합니다.
* 종목 미선택 시 안내 메시지를 표시합니다.
*/
interface AiAnalysisPanelProps {
/** AI 분석 데이터 (analysis: 포맷된 텍스트, data: 원시 데이터) */
aiAnalysisData: { analysis: string; data: any } | null | undefined
}
export const AiAnalysisPanel = React.memo(({ aiAnalysisData }: AiAnalysisPanelProps) => {
const aiAnalysisText = aiAnalysisData?.analysis || null
return (