---
name: data_table_chips
kind: function
lang: cpp
domain: viz
version: "1.0.0"
purity: impure
signature: "void data_table::draw_filter_chips(Stage& stg, const char* const* eff_headers, int eff_cols, const std::vector<ColumnType>& eff_types)"
description: "Barra de chips superior de la tabla TQL: render y edicion de filtros activos, breakouts (group-by), agregaciones, sorts, joins con tablas secundarias, header-menu de columna (sort/filter/conditional-color/type-change), y area TQL (Show TQL / Apply TQL / Save .tql / Load .tql). Es la sub-funcion mas grande del refactor 0107c (~1000 LOC, 17 funciones). Sub-funcion extraida de modules/data_table/data_table.cpp (issue 0107c)."
tags: [viz, table, imgui, ui, chips, filters, sort, aggregation, tql, cpp-tables, joins]
uses_functions:
  - data_table_color_rules_cpp_viz
  - data_table_cpp_viz
  - tql_emit_cpp_core
  - tql_apply_cpp_core
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_chips.cpp"
framework: imgui
params:
  - name: stg
    desc: "Stage activo (st.stages[active]): contiene filters, breakouts, aggregations, sorts, derived. Mutado por todos los chips y popups de edicion."
  - name: eff_headers / eff_cols
    desc: "Headers y numero de columnas efectivas del stage activo (orig + derived). Usados en labels de chips y en los popups de anadir/editar."
  - name: eff_types
    desc: "Tipos de columna efectivos. Usados para filtrar los operadores disponibles (draw_typed_ops) y para formatear los popups."
  - name: st (para joins y header-menu)
    desc: "State completo: necesario para draw_joins_chips (accede a st.stages) y draw_header_menu (accede a st.color_rules, st.col_visible)."
  - name: joinables (para joins)
    desc: "Vector de TableInput secundarias disponibles para join. Si vacio, draw_joins_chips no muestra nada."
output: "Void. Todos los efectos son mutaciones de stg (Stage) o st (State) en respuesta a la interaccion del usuario."
---

## Documentacion

Sub-funcion mas grande del refactor 0107c. Encapsula toda la UI de la barra de chips de la tabla TQL.

### Mapa de funciones

| Funcion | LOC aprox | Responsabilidad |
|---|---|---|
| `draw_filter_chips` | ~85 | Chips de filtros activos con X para borrar |
| `draw_add_filter_popup` | ~55 | Popup para anadir filtro nuevo |
| `draw_edit_filter_popup` | ~42 | Popup edicion de filtro existente (right-click en chip) |
| `draw_breakout_chips` | ~93 | Chips de breakout activos con X |
| `draw_add_breakout_popup` | ~34 | Popup anadir breakout (col de agrupacion) |
| `draw_edit_breakout_popup` | ~24 | Popup edicion breakout |
| `draw_aggregation_chips` | ~50 | Chips de agregaciones activas con X |
| `draw_add_aggregation_popup` | ~50 | Popup anadir agregacion (Count, Sum, Mean, ...) |
| `draw_edit_agg_popup` | ~48 | Popup edicion agregacion |
| `draw_sort_chips` | ~70 | Chips de sort activos con X |
| `draw_add_sort_popup` | ~26 | Popup anadir sort |
| `draw_edit_sort_popup` | ~26 | Popup edicion sort |
| `apply_header_sort_click` | ~17 | Sort al click en cabecera (Asc/Desc/none ciclo) |
| `draw_joins_chips` | ~107 | Chips de joins con tablas secundarias |
| `draw_header_menu` | ~209 | Menu contextual de columna (sort/filter/color/type) |
| `draw_typed_ops` | ~8 | Radio buttons de Op segun tipo de columna |
| `type_supports_range` | ~3 | Bool tipo soporta rango |
| `draw_tql_bar` | ~95 | Botones + modales TQL show/apply/save/load |

### Orden de llamada en el chrome

```cpp
// Stage 0 (chrome_visible):
draw_joins_chips(st, joinables, hdrs, cols, types);
draw_filter_chips(act, hdrs, cols, types);
draw_add_filter_popup(act, hdrs, cols, types);
draw_edit_filter_popup(act, hdrs, cols, types);
draw_breakout_chips(act, hdrs, cols, types);
// ... etc.
draw_sort_chips(act);
draw_tql_bar(tql_bar, st, orig_headers, orig_types, cells, rows, orig_cols);
```

## Ejemplo

```cpp
// Bloque chrome stage 0:
if (chrome_visible) {
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8, 2));

    data_table::draw_filter_chips(act, eff_headers, eff_cols, eff_types);
    data_table::draw_add_filter_popup(act, eff_headers, eff_cols, eff_types);
    data_table::draw_edit_filter_popup(act, eff_headers, eff_cols, eff_types);

    data_table::draw_breakout_chips(act, eff_headers, eff_cols, eff_types);
    // ...

    data_table::draw_sort_chips(act);
    data_table::draw_add_sort_popup(act, eff_headers, eff_cols, eff_types);
    data_table::draw_edit_sort_popup(act, eff_headers, eff_cols);

    data_table::draw_tql_bar(U.tql_bar, st, orig_h, orig_t, cells, rows, orig_cols);

    ImGui::PopStyleVar();
}
```

## Cuando usarla

Llamar desde el entrypoint thin `data_table::render()` en el bloque `chrome_visible`. El orden importa: joins primero, luego filtros, breakouts, agregaciones, sorts, TQL bar. No llamar fuera del contexto de un frame ImGui activo.

## Gotchas

- `draw_header_menu` DEBE llamarse desde dentro del popup de cabecera (`ImGui::BeginPopupContextItem`) — no se puede llamar en el loop normal de render.
- Los popups de add/edit usan IDs de ImGui fijos (`"##addf"`, `"##editf"`, etc.). Si se tienen multiples instancias de data_table en la misma ventana, usar `ImGui::PushID(table_id)` antes de llamar a los chips.
- `draw_tql_bar` incluye los modales "Show TQL" y "Apply TQL" via `ImGui::BeginPopupModal`. Deben llamarse fuera del bloque `PushStyleVar` si los estilos interfieren con el modal.
- `apply_header_sort_click` sin Shift reemplaza TODOS los sorts existentes por el nuevo. Es el comportamiento esperado para click simple. Shift agrega sort secundario.
- `draw_joins_chips` asume que `joinables` es la slice de `tables` excluyendo la tabla principal. Si se pasa la tabla principal como joinable, se creara un self-join.
