# Migrate From Direct D3

Direct D3 charts often mix data preparation, scale construction, layout, DOM joins, transition state, gestures, and application UI. Keep proven algorithms; migrate ownership boundary by boundary.

## Classify Existing Code

| D3 code                           | Usually keep first                          | TanStack destination                                     |
| --------------------------------- | ------------------------------------------- | -------------------------------------------------------- |
| `d3-array` aggregation/statistics | yes, if tested and semantic                 | prepared rows or later TanStack transform                |
| `d3-time` interval policy         | yes                                         | prepared rows, domains, tick values                      |
| scale domain construction         | preserve semantic policy                    | configured scale instance/factory                        |
| scale pixel range                 | no                                          | Charts assigns final responsive range                    |
| shape/layout algorithm            | keep if unsupported or application-specific | feed rows to marks or resolved-layout extension          |
| selection/data join               | no                                          | scene reconciliation through mark/datum identity         |
| axis DOM rendering                | no                                          | chart guides                                             |
| transition mutation               | no                                          | SVG animation or motion renderer                         |
| pointer/brush/zoom DOM listeners  | classify product policy                     | first-party controlled control or application controller |
| HTML overlay                      | maybe                                       | application UI anchored from scene/point semantics       |

## Sequence

1. Freeze prepared rows, domains, and layout outputs as fixtures.
2. Replace DOM joins with built-in marks using the same rows and stable keys.
3. Move axis and legend ownership to the definition.
4. Remove authored positional ranges; let final layout assign them.
5. Replace transition code after static/update geometry matches.
6. Replace gestures with controlled semantic state after focus behavior matches.
7. Move a D3 algorithm only when the native transform/layout proves equivalent.

## Extension Boundary

Keep an existing D3 algorithm when it produces meaningful data-space rows or a final-bounds topology that TanStack does not own. Wrap it in the narrowest correct layer:

- application transform for reusable semantic rows;
- built-in marks for the output geometry;
- resolved-layout custom mark for final-pixel topology;
- renderer/host extension only for genuinely platform-specific behavior.

Do not call D3 selection APIs from scene generation.

## Parity Cases

- Data join keys through insert, delete, and reorder.
- Domain and tick behavior at empty, negative, log-invalid, and missing cases.
- Resize with measured margins and any final-bounds layout.
- Interrupted transitions and active focus.
- Gesture cancellation, keyboard alternative, and teardown.
- Packed bundle no longer retains obsolete D3 DOM/gesture modules.

Source: `docs/guides/migrating.md`; `docs/concepts/scales-and-d3.md`; `docs/guides/custom-marks-and-renderers.md`
