---
name: data_table_drill
kind: function
lang: cpp
domain: viz
version: "1.0.0"
purity: impure
signature: "void data_table::drill_into(State& st, int from_stage, const std::string& col_name, const std::string& value, const std::vector<std::string>& prev_input_headers)"
description: "Drill-down stack + UI breadcrumb para la tabla TQL. Gestiona el arbol de navegacion de stages: drill_into anade un filtro Op::Eq al stage previo y avanza al nivel de detalle, draw_stage_breadcrumb dibuja los botones de navegacion (< back, > forward, ^ up) y el selector de stages activo. Sub-funcion extraida de modules/data_table/data_table.cpp (issue 0107c)."
tags: [viz, table, imgui, ui, drill-down, navigation, tql, cpp-tables]
uses_functions:
  - data_table_cpp_viz
uses_types:
  - data_table_types_cpp_core
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [imgui]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/viz/data_table_drill.cpp"
framework: imgui
params:
  - name: st
    desc: "State mutable que contiene st.stages, st.active_stage, st.drill_back (undo stack), st.drill_forward (redo stack). Todos son mutados por las funciones de este modulo."
  - name: from_stage
    desc: "Stage desde el que se origina el drill (stage activo al hacer right-click en una celda de breakout). Debe ser > 0 para que haya stage previo donde anadir el filtro."
  - name: col_name
    desc: "Nombre de la columna breakout sobre la que se drilla (debe existir en prev_input_headers)."
  - name: value
    desc: "Valor de la celda seleccionada. Se aplica como Filter Op::Eq en el stage from_stage-1."
  - name: prev_input_headers
    desc: "Headers del INPUT del stage from_stage (= output del stage from_stage-1). Necesarios para traducir col_name a col_idx."
output: "Void. Mutates st.stages[target].filters, st.active_stage, st.drill_back, st.drill_forward."
---

## Documentacion

Sub-funcion que encapsula la logica de drill-down de la tabla TQL. El drill-down permite al usuario hacer right-click en una celda de una columna breakout (stage > 0) y "entrar" al detalle del grupo seleccionado anadiendo un filtro al stage previo.

### Funciones publicas

| Funcion | Uso |
|---|---|
| `make_drill_filter(col_idx, value)` | Helper: crea `Filter{col_idx, Op::Eq, value}`. |
| `apply_drill_step(st, step)` | Inserta `step.added` en `st.stages[step.target_stage].filters` y actualiza `st.active_stage`. |
| `undo_drill_step(st, step)` | Invierte `apply_drill_step`: elimina el filtro y restaura `st.active_stage`. |
| `drill_up(st)` | Decrementa `st.active_stage` en 1 (sin crear entry en el undo stack). |
| `drill_into(st, from, col, val, hdrs)` | API publica: compone make_drill_filter + apply_drill_step + graba en drill_back + limpia drill_forward. |
| `draw_stage_breadcrumb(st)` | UI: botones < > ^ + combo de stages. |

### Invariante del stack

- `st.drill_back`: historial de drill steps (undo). Cada `drill_into` agrega al final.
- `st.drill_forward`: pasos deshecho (redo). Se limpia en cada `drill_into` nueva.
- `drill_up` NO agrega al stack — es un atajo que no se puede rehacer.

## Ejemplo

```cpp
// En el cell popup de una celda de breakout col (stage > 0):
if (ImGui::MenuItem(lbl)) {
    data_table::drill_into(st, active_stage,
        cur_headers[col], cell_value,
        input_headers_active);
    ImGui::CloseCurrentPopup();
}

// Breadcrumb al inicio del area de chrome:
if (chrome_visible) {
    data_table::draw_stage_breadcrumb(st);
}
```

## Cuando usarla

`drill_into` se llama desde el popup de celda en `data_table_grid_cpp_viz` cuando el usuario hace right-click en una columna breakout. `draw_stage_breadcrumb` se llama una vez por frame en el area de chrome antes de los chips.

## Gotchas

- `drill_into` requiere `from_stage > 0`. Si `from_stage <= 0` la funcion retorna sin hacer nada (no hay stage previo).
- `col_name` debe existir en `prev_input_headers`; si no se encuentra, la funcion retorna sin efecto (el filter no se anade).
- `apply_drill_step` y `undo_drill_step` modifican `st.stages[step.target_stage].filters` por posicion (`filter_pos`). Hay un riesgo de corrupcion si los filtros del stage cambian entre apply y undo por otra via. El design actual asume que el caller no muta los filtros del stage target fuera de este API.
- `draw_stage_breadcrumb` dibuja los botones en linea horizontal; si el area es muy estrecha (< 120px) los botones solapan. El caller debe asegurar suficiente ancho o usar `ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ...)`.
