# @cdc/chart — Package Rules

## Entry Point Pattern
- `CdcChart.tsx` (wrapper) — handles data fetching, config loading, CSV parsing. Does NOT set up state or context.
- `CdcChartComponent.tsx` (main, ~1540 lines) — sets up useReducer, both context providers, data transformation, and chart rendering orchestration.
- Do not confuse the two. Data loading changes go in the wrapper; rendering/state changes go in the main component.

## Chart Types
Each visualization type is a **separate component** in `src/components/`:

| visualizationType | Component | Notes |
|---|---|---|
| `'Bar'` | `BarChart/` | Has sub-components: Horizontal, Vertical, StackedHorizontal, StackedVertical |
| `'Line'` | `LineChart/` | Circle and BumpCircle sub-components |
| `'Pie'` | `PieChart/` | |
| `'Scatter Plot'` | `ScatterPlot/` | |
| `'Area Chart'` | `AreaChart/` | |
| `'Box Plot'` | `BoxPlot/` | |
| `'Forest Plot'` | `ForestPlot/` | |
| `'Sankey'` | `Sankey/` | Uses d3-sankey |
| `'Bump Chart'` | `BumpChart/` | |
| `'Combo'` | `Combo/` | Mixed bar + line |
| `'Forecasting'` | `Forecasting/` | |
| `'Deviation Bar'` | `DeviationBar/` | |
| `'Paired Bar'` | `PairedBar/` | |
| `'Spark Line'` | `Sparkline/` | |
| `'Warming Stripes'` | `WarmingStripes/` | |

CdcChartComponent routes to the correct component based on `config.visualizationType`:
- Pie → `<PieChart />`
- Sankey → `<SankeyChart />`
- Spark Line → `<SparkLine />`
- Everything else → `<LinearChart />` (shared SVG container)

## State Management

### Actions (16 types in `store/chart.actions.ts`):
`SET_CONFIG`, `UPDATE_CONFIG`, `SET_COLOR_SCALE`, `SET_STATE_DATA`, `SET_EXCLUDED_DATA`, `SET_FILTERED_DATA`, `SET_SERIES_HIGHLIGHT`, `SET_VIEWPORT`, `SET_VIZ_VIEWPORT`, `SET_DIMENSIONS`, `SET_CONTAINER`, `SET_LOADED_EVENT`, `SET_DRAG_ANNOTATIONS`, `SET_LOADING`, `SET_BRUSH_DATA`

### Context (`ConfigContext.tsx`):
- `ConfigContext` — read-only state (ChartContext type)
- `ChartDispatchContext` — dispatch function
- ChartContext provides: `config`, `colorScale`, `transformedData`, `rawData`, `tableData`, formatting functions (`formatDate`, `formatNumber`, `parseDate`), accessibility helpers, refs (`legendRef`, `parentRef`, `svgRef`), viewport info, and editor flags.

## Key Hooks (in `src/hooks/`)
- `useScales` (528 lines) — generates xScale, yScale, seriesScale for all chart types. Returns `{ xScale, yScale, seriesScale, min, max, leftMax, rightMax }`.
- `useTooltip` (720 lines) — tooltip mouse handlers, series filtering, formatting. Returns handlers and `TooltipListItem` component.
- `useReduceData` — memoized min/max/stats computation.
- `useRightAxis` — dual Y-axis support (series can specify `axis: 'right'`).
- `useHighlightedBars` — bar highlighting logic.
- `useIntersectionObserver` — lazy loading / viewport detection.

## Where to Put New Code

| What you're adding | Where it goes |
|---|---|
| New chart type | `src/components/<ChartType>/` with `index.tsx` exporting main component |
| Chart-specific helper | `src/helpers/<name>.ts` |
| Chart-specific hook | `src/hooks/use<Name>.ts` |
| Chart-specific type | `src/types/<Name>.ts` |
| New action | `src/store/chart.actions.ts` (add type) + `src/store/chart.reducer.ts` (add case) |
| Story | `src/_stories/<ChartType>.stories.tsx` with mock data in `src/_stories/_mock/` |

## Non-Obvious Patterns
- **Runtime config**: `config.runtime` is computed at render time by `getNewRuntime()` — contains `seriesKeys`, `seriesLabelsAll`, `barSeriesKeys`, `lineSeriesKeys`. Not part of initial state.
- **Dynamic categories**: Series can have `dynamicCategory` field where the series key becomes a category value from pivoted data. Check `originalDataKey` for the source column.
- **Brush data priority**: `getTransformedData()` uses brushData > filteredData > excludedData (first non-empty wins).
- **Two viewports**: `currentViewport` = overall container size, `vizViewport` = chart area only. Tick counts and legend layout depend on these.
- **Color scale precedence**: `customColorsOrdered` (1:1 mapping) > `customColors` > palette name > fallback palette.
- **Preliminary data / suppression**: `config.preliminaryData` stores effect/suppression icons that affect legend, tooltips, and line styles.
- **Image ID**: Each chart gets a unique `imageId` (`cove-<random>`) for SVG gradient/pattern IDs to avoid collisions when multiple charts are on one page.
- **Line-to-bar conversion**: `allowLineToBarGraph` + `isConvertLineToBarGraph()` — line charts can auto-convert to bars under certain conditions.
- **Small multiples**: `config.smallMultiples.mode` can be `'by-column'` or `'by-series'`. Each tile gets its own data slice. `synchronizedTooltips` enables cross-tile hover.

## SCSS
- `src/scss/main.scss` — all styles scoped under `.cdc-open-viz-module.type-chart`
- Imports `@cdc/core/styles/utils/breakpoints` for responsive mixins
- Animation keyframes: `revealLolly`, `dash`, `growBar`, `growBarH`
- Legend positions: `.legend-top`, `.legend-left`, `.legend-right`, `.legend-bottom`
