"use client"; import React, { useState, useCallback } from "react"; import { ChartConfig, QueryResult } from "./types"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Label } from "@/components/ui/label"; import { Card } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Checkbox } from "@/components/ui/checkbox"; import { Separator } from "@/components/ui/separator"; import { Settings, TrendingUp, AlertCircle } from "lucide-react"; interface ChartConfigPanelProps { config?: ChartConfig; queryResult?: QueryResult; onConfigChange: (config: ChartConfig) => void; chartType?: string; } /** * 차트 설정 패널 컴포넌트 * - 데이터 필드 매핑 설정 * - 차트 스타일 설정 * - 실시간 미리보기 */ export function ChartConfigPanel({ config, queryResult, onConfigChange, chartType }: ChartConfigPanelProps) { const [currentConfig, setCurrentConfig] = useState(config || {}); // 원형/도넛 차트는 Y축이 필수가 아님 const isPieChart = chartType === "pie" || chartType === "donut"; // 설정 업데이트 const updateConfig = useCallback( (updates: Partial) => { const newConfig = { ...currentConfig, ...updates }; setCurrentConfig(newConfig); onConfigChange(newConfig); }, [currentConfig, onConfigChange], ); // 사용 가능한 컬럼 목록 const availableColumns = queryResult?.columns || []; const sampleData = queryResult?.rows?.[0] || {}; return (
{/* 데이터 필드 매핑 */} {queryResult && ( <> {/* 차트 제목 */}
updateConfig({ title: e.target.value })} placeholder="차트 제목을 입력하세요" />
{/* X축 설정 */}
{/* Y축 설정 (다중 선택 가능) */}
{availableColumns.map((col) => { const isSelected = Array.isArray(currentConfig.yAxis) ? currentConfig.yAxis.includes(col) : currentConfig.yAxis === col; return (
{ const currentYAxis = Array.isArray(currentConfig.yAxis) ? currentConfig.yAxis : currentConfig.yAxis ? [currentConfig.yAxis] : []; let newYAxis: string | string[]; if (checked) { newYAxis = [...currentYAxis, col]; } else { newYAxis = currentYAxis.filter((c) => c !== col); } // 단일 값이면 문자열로, 다중 값이면 배열로 if (newYAxis.length === 1) { newYAxis = newYAxis[0]; } updateConfig({ yAxis: newYAxis }); }} />
); })}

팁: 여러 항목을 선택하면 비교 차트가 생성됩니다 (예: 갤럭시 vs 아이폰)

{/* 집계 함수 */}

집계 함수는 현재 쿼리 결과에 적용되지 않습니다. SQL 쿼리에서 직접 집계하는 것을 권장합니다.

{/* 그룹핑 필드 (선택사항) */}
{/* 차트 색상 */}
{[ ["#3B82F6", "#EF4444", "#10B981", "#F59E0B"], // 기본 ["#8B5CF6", "#EC4899", "#06B6D4", "#84CC16"], // 밝은 ["#1F2937", "#374151", "#6B7280", "#9CA3AF"], // 회색 ["#DC2626", "#EA580C", "#CA8A04", "#65A30D"], // 따뜻한 ].map((colorSet, setIdx) => ( ))}
{/* 범례 표시 */}
updateConfig({ showLegend: checked as boolean })} />
{/* 설정 미리보기 */}
설정 미리보기
X축: {currentConfig.xAxis || "미설정"}
Y축: {Array.isArray(currentConfig.yAxis) && currentConfig.yAxis.length > 0 ? `${currentConfig.yAxis.length}개 (${currentConfig.yAxis.join(", ")})` : currentConfig.yAxis || "미설정"}
집계: {currentConfig.aggregation || "없음"}
{currentConfig.groupBy && (
그룹핑: {currentConfig.groupBy}
)}
데이터 행 수: {queryResult.rows.length}개
{Array.isArray(currentConfig.yAxis) && currentConfig.yAxis.length > 1 && (
✨ 다중 시리즈 차트가 생성됩니다!
)}
{/* 필수 필드 확인 */} {(!currentConfig.xAxis || !currentConfig.yAxis) && ( X축과 Y축을 모두 설정해야 차트가 표시됩니다. )} )}
); }