핵심 개념
opt-charts를 opt-ui 내부 visuals의 부속물이 아니라 독립 데이터 시각화 패키지로 운영하기 위한 책임 경계와 구성 원칙입니다.
reopt designUpdated
1. 패키지 구조
opt-charts는 opt-ui의 Core/Shells/Surfaces 계층과 분리된 데이터 시각화 패키지입니다. Recharts 의존성과 chart-specific shell을 이 패키지 안에서 끝내면 opt-ui가 일반 인터페이스 컴포넌트와 차트 엔진을 동시에 소유하는 문제가 줄어듭니다.
@reopt-ai/opt-charts
├─ visuals
│ ├─ ChartContainer, ChartTooltipContent, ChartLegendContent
│ ├─ LineChart, BarChart, AreaChart, PieChart, ScatterChart, BubbleChart
│ ├─ Heatmap, RetentionHeatmap, CalendarHeatmap, Treemap, Sunburst, VennDiagram
│ ├─ SankeyChart, PathFlowChart, FunnelChart, WaterfallChart
│ └─ TimeSeriesChart, SmallMultiples, TraceWaterfall, GanttChart, CandlestickChart
├─ shells
│ ├─ MetricsCard, TrendChart, EventSparkline
│ └─ ReportWidget
├─ time (server-safe)
│ └─ date math, time range, bucket and tick helpers
└─ shared exports
├─ ChartDataPoint, ChartSeriesDef, ChartConfig, ChartMargin
└─ seriesColor, CHART_COLOR_DOMAINS, locale formatters| 경계 | 소유 | 피해야 할 것 |
|---|---|---|
| visuals | 차트 렌더링, 축/그리드/tooltip/legend, SVG/table 기반 분석 시각화 | 카드 헤더, 비즈니스 상태, report builder 설정 화면 |
| shells | MetricsCard, TrendChart, EventSparkline, ReportWidget처럼 제품 화면 조합 | 새 chart primitive 추가, 데이터 정규화 책임 |
| consumer app | 원천 데이터 fetch, 단위/통화 formatter, empty/error/loading 정책 | opt-charts 내부 palette나 Recharts DOM 구조에 직접 의존 |
2. ChartContainer
ChartContainer는 모든 Recharts 기반 chart의 sizing과 accessibility root입니다. 직접 Recharts 컴포넌트를 감싸야 할 때도 이 컨테이너를 사용하면 기존 token, height, ResponsiveContainer 초기 dimension 동작을 유지할 수 있습니다.
import { ChartContainer } from "@reopt-ai/opt-charts";
import { LineChart as RechartsLineChart, Line } from "recharts";
export function CustomChart() {
return (
<ChartContainer height={300} aria-label="주간 활성 사용자">
<RechartsLineChart data={data} accessibilityLayer>
<Line dataKey="activeUsers" />
</RechartsLineChart>
</ChartContainer>
);
}3. Visuals vs Shells
visuals는 행·시리즈, 행렬, 계층, 그래프, 구간 또는 스칼라 등 각 유형의 데이터 모델을 받아 차트를 그립니다. shells는 화면 안에서 제목, 설명, 지표 값, 카드 chrome, lazy chart loading 같은 제품 조합을 제공합니다. 같은 차트라도 상세 분석 페이지는 visual을 직접 쓰고, 운영 대시보드 카드에서는 shell을 선택합니다.
import { MetricsCard, TrendChart } from "@reopt-ai/opt-charts";
export function RevenuePanel() {
return (
<section className="grid gap-4 lg:grid-cols-[18rem_1fr]">
<MetricsCard
title="ARR"
value="₩18.4억"
change="+12.8%"
trend="up"
sparklineData={[20, 24, 23, 31, 36, 42]}
/>
<TrendChart
title="월별 매출"
data={data}
series={series}
chartProps={{ showTooltip: true, showLegend: true }}
/>
</section>
);
}4. 운영 개념
ChartContainer
Recharts ResponsiveContainer 래퍼입니다. width는 100%, height 기본값은 300이며 기본 role="img"와 aria 속성을 root div에 전달합니다. interactive이면 role="group"으로 범례 버튼 같은 자식 컨트롤을 보존합니다.
accessibilityLayer
LineChart, BarChart, AreaChart, PieChart, ScatterChart, BubbleChart 등 Recharts 기반 차트는 accessibilityLayer를 켭니다.
formatter boundary
단위, 통화, 퍼센트 표기는 tooltipOptions, legendOptions, valueFormatter, labelFormatter에서 주입합니다.
token boundary
명시적 color가 우선입니다. seriesColor는 16개 테마 categorical 토큰을 차례로 쓰고 이후에는 중립색을 사용합니다. 크기와 양극성은 sequential/diverging 색상 도메인으로 구분합니다.