Files
vexplor/frontend/components/admin/dashboard/charts/ChartRenderer.tsx
hjjeong 5f63c24c42 feat: 대시보드 관리 시스템 구현
## 백엔드
- DashboardController: 대시보드 CRUD 및 쿼리 실행 API
- DashboardService: 비즈니스 로직 처리
- PostgreSQL 연동 및 데이터 관리

## 프론트엔드
- DashboardDesigner: 캔버스 기반 대시보드 디자이너
- QueryEditor: SQL 쿼리 편집 및 미리보기
- ChartRenderer: 다양한 차트 타입 지원 (Bar, Line, Area, Donut, Stacked, Combo)
- DashboardViewer: 실시간 데이터 반영 뷰어

## 개선사항
- 콘솔 로그 프로덕션 준비 (주석 처리)
- 차트 컴포넌트 확장 (6가지 타입)
- 실시간 쿼리 실행 및 데이터 바인딩
2025-10-01 12:06:24 +09:00

103 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import React from 'react';
import { DashboardElement, QueryResult } from '../types';
import { BarChartComponent } from './BarChartComponent';
import { PieChartComponent } from './PieChartComponent';
import { LineChartComponent } from './LineChartComponent';
import { AreaChartComponent } from './AreaChartComponent';
import { StackedBarChartComponent } from './StackedBarChartComponent';
import { DonutChartComponent } from './DonutChartComponent';
import { ComboChartComponent } from './ComboChartComponent';
interface ChartRendererProps {
element: DashboardElement;
data?: QueryResult;
width?: number;
height?: number;
}
/**
* 차트 렌더러 컴포넌트 (단순 버전)
* - 데이터를 받아서 차트에 그대로 전달
* - 복잡한 변환 로직 제거
*/
export function ChartRenderer({ element, data, width = 250, height = 200 }: ChartRendererProps) {
// console.log('🎬 ChartRenderer:', {
// elementId: element.id,
// hasData: !!data,
// dataRows: data?.rows?.length,
// xAxis: element.chartConfig?.xAxis,
// yAxis: element.chartConfig?.yAxis
// });
// 데이터나 설정이 없으면 메시지 표시
if (!data || !element.chartConfig?.xAxis || !element.chartConfig?.yAxis) {
return (
<div className="w-full h-full flex items-center justify-center text-gray-500 text-sm">
<div className="text-center">
<div className="text-2xl mb-2">📊</div>
<div> </div>
<div className="text-xs mt-1"> </div>
</div>
</div>
);
}
// 데이터가 비어있으면
if (!data.rows || data.rows.length === 0) {
return (
<div className="w-full h-full flex items-center justify-center text-red-500 text-sm">
<div className="text-center">
<div className="text-2xl mb-2"></div>
<div> </div>
</div>
</div>
);
}
// 데이터를 그대로 전달 (변환 없음!)
const chartData = data.rows;
// console.log('📊 Chart Data:', {
// dataLength: chartData.length,
// firstRow: chartData[0],
// columns: Object.keys(chartData[0] || {})
// });
// 차트 공통 props
const chartProps = {
data: chartData,
config: element.chartConfig,
width: width - 20,
height: height - 60,
};
// 차트 타입에 따른 렌더링
switch (element.subtype) {
case 'bar':
return <BarChartComponent {...chartProps} />;
case 'pie':
return <PieChartComponent {...chartProps} />;
case 'line':
return <LineChartComponent {...chartProps} />;
case 'area':
return <AreaChartComponent {...chartProps} />;
case 'stacked-bar':
return <StackedBarChartComponent {...chartProps} />;
case 'donut':
return <DonutChartComponent {...chartProps} />;
case 'combo':
return <ComboChartComponent {...chartProps} />;
default:
return (
<div className="w-full h-full flex items-center justify-center text-gray-500 text-sm">
<div className="text-center">
<div className="text-2xl mb-2"></div>
<div> </div>
</div>
</div>
);
}
}