Arquitectura de Señales en Vega: El Estándar Profesional

csalcedodatabi Tutorial Template Arquitectura
Arquitectura de señales en Vega - Universal KPI Trend Matrix mostrando sistema de prefijos UI_, DATA_, LAYOUT_ y STATE_

Por qué escribí esto

Después de +2 años desarrollando visuales custom con Vega y Vega-Lite en Deneb para Power BI, aprendí una lección por las malas: el código que escribes hoy lo mantendrás mañana.

No existe un curso de Arquitectura Vega 101. Lo que vas a leer es el resultado de abrir archivos JSON que yo mismo escribí hace meses y no entender nada, de refactorizar el mismo visual 5 veces, y de finalmente encontrar patrones que realmente funcionan.

Si eres nuevo en Vega, esto te ahorrará meses de frustración.
Si ya tienes experiencia, encontrarás al menos una técnica que aplicarás en tu próximo proyecto.


💡 La idea clave: Sistema de prefijos (UI_, DATA_, LAYOUT_, STATE_) + agrupación en objetos = visuales mantenibles, escalables y profesionales.


📌 Nota: Vega vs Vega-Lite

Este artículo usa sintaxis de Vega (signals), pero el sistema de arquitectura aplica igual para Vega-Lite.

VegaVega-Lite
”signals”: […]“params”: […]
{“signal”: “UI_Colors.primary”}{“expr”: “UI_Colors.primary”}

Ejemplo de conversión:

// Vega
"signals": [
  {"name": "UI_Colors", "value": {"primary": "#3B82F6"}}
]

// Vega-Lite
"params": [
  {"name": "UI_Colors", "value": {"primary": "#3B82F6"}}
]

La arquitectura es idéntica — solo cambia el nombre del contenedor.


El Problema

Abres un JSON de Vega que creaste hace 3 meses:

"signals": [
  {"name": "c1", "value": "#3B82F6"},
  {"name": "fs", "value": 14},
  {"name": "w", "value": 400}
]

¿Qué es c1? ¿fs es font-size? ¿De qué elemento?

Este artículo resuelve exactamente ese problema.


La Solución: 4 Prefijos que Recomiendo

PrefijoPropósitoEjemplo
UI_Estilos y coloresUI_Colors, UI_Typography
DATA_Valores del datasetDATA_MaxValue, DATA_Categories
LAYOUT_Geometría responsiveLAYOUT_ChartWidth, LAYOUT_Columns
STATE_Interacción del usuarioSTATE_HoveredItem, STATE_Selected

UI_ — Estilos Visuales

Todo lo que el usuario puede personalizar: colores, fuentes, geometría.

Ejemplo: Paleta de Colores

{
  "name": "UI_Colors",
  "description": "Paleta de colores del visual",
  "value": {
    "primary": "#3B82F6",
    "background": "#FFFFFF",
    "positive": "#10B981",
    "negative": "#EF4444"
  }
}

Ejemplo: Tipografía

{
  "name": "UI_Typography",
  "description": "Configuración de fuentes",
  "value": {
    "fontFamily": "Segoe UI",
    "titleSize": 18,
    "bodySize": 12
  }
}

DATA_ — Datos Derivados

Valores extraídos o calculados del dataset.

Ejemplo: Valor Máximo

{
  "name": "DATA_MaxValue",
  "description": "Valor máximo para escalar el eje Y",
  "update": "data('dataset')[0]['__max__']"
}

Ejemplo: Lista de Categorías

{
  "name": "DATA_Categories",
  "description": "Lista única de categorías",
  "update": "pluck(data('dataset'), 'category')"
}

LAYOUT_ — Geometría Reactiva

Cálculos de posicionamiento que reaccionan al contenedor.

Ejemplo: Ancho Responsive

{
  "name": "LAYOUT_ChartWidth",
  "description": "Ancho del gráfico (responsive)",
  "update": "containerSize()[0] - 80"
}

Ejemplo: Columnas Dinámicas

{
  "name": "LAYOUT_Columns",
  "description": "Columnas según ancho",
  "update": "containerSize()[0] < 600 ? 2 : containerSize()[0] < 900 ? 3 : 4"
}

STATE_ — Interacción

Variables que cambian con acciones del usuario.

Ejemplo: Hover State

{
  "name": "STATE_HoveredItem",
  "description": "ID del elemento bajo el mouse",
  "value": null,
  "on": [
    {"events": "rect:mouseover", "update": "datum.id"},
    {"events": "rect:mouseout", "update": "null"}
  ]
}

Agrupación en Objetos

❌ Sopa de Variables

"signals": [
  {"name": "ColorFondo", "value": "#FFFFFF"},
  {"name": "ColorBorde", "value": "#E5E7EB"},
  {"name": "TamanoTitulo", "value": 18},
  {"name": "TamanoSubtitulo", "value": 14}
  // ... 50 variables más
]

✅ Objetos Semánticos

"signals": [
  {
    "name": "UI_Colors",
    "value": {"background": "#FFFFFF", "border": "#E5E7EB"}
  },
  {
    "name": "UI_Typography", 
    "value": {"titleSize": 18, "subtitleSize": 14}
  }
]

De 50+ variables a 4-5 objetos organizados.


Reglas de Oro

  1. Máximo 1 nivel de profundidad en objetos
  2. Máximo 10 propiedades por objeto
  3. Siempre description en cada señal
  4. Un objeto = una responsabilidad

value vs update

PropiedadCuándo UsarEjemplo
valueValores estáticosUI_Colors
updateValores dinámicosLAYOUT_ChartWidth
onEventos de usuarioSTATE_HoveredItem

Ejemplo Completo

"signals": [
  {
    "name": "UI_Colors",
    "description": "Paleta de colores",
    "value": {
      "barFill": "#3B82F6",
      "barHover": "#2563EB",
      "background": "#FFFFFF"
    }
  },
  {
    "name": "LAYOUT_ChartWidth",
    "description": "Ancho responsive del gráfico",
    "update": "containerSize()[0] - 80"
  },
  {
    "name": "DATA_MaxValue",
    "description": "Máximo para escala Y",
    "update": "data('dataset')[0]['__max__']"
  },
  {
    "name": "STATE_HoveredBar",
    "description": "Barra bajo el mouse",
    "value": null,
    "on": [
      {"events": "rect:mouseover", "update": "datum.id"},
      {"events": "rect:mouseout", "update": "null"}
    ]
  }
]

Uso en Marks:

"fill": [
  {"test": "datum.id === STATE_HoveredBar", "signal": "UI_Colors.barHover"},
  {"signal": "UI_Colors.barFill"}
]

🎯 Caso Real: Universal KPI Trend Matrix

La teoría está bien, pero ¿cómo se ve esto en un visual real de producción?

Este es el Universal KPI Trend Matrix, un visual que desarrollé aplicando exactamente esta arquitectura. Veamos cómo se implementan las señales:

UI_FontSizes y UI_FontWeights — Tipografía Centralizada

Señales UI para tipografía centralizada - Configuración de tamaños de fuente en un solo objeto

En la imagen puedes ver:

  • UI_FontSizes: Un objeto que agrupa TODOS los tamaños de fuente del visual (encabezados, KPIs, subtítulos, ejes)
  • UI_FontWeights: Controla el grosor de cada elemento textual (normal, bold, bolder)

¿El beneficio? Cambiar la tipografía de todo el visual = modificar 2 objetos. No 20 variables dispersas.


UI_FontWeights — Control de Estilos de Texto

Señales UI para pesos de fuente - Control centralizado de font-weight

Aquí vemos cómo las señales UI_ controlan el estilo visual del texto:

  • UI_FontWeights: Define el grosor de cada elemento textual
  • Valores: normal, bold, bolder para diferentes jerarquías

Esto permite que todos los estilos de texto se configuren desde un solo lugar.


LAYOUT_CardDimensions, GridConfig y Spacing — El Sistema de Grid

Señales LAYOUT para sistema de grid responsive - Configuración de dimensiones y espaciado

El corazón del layout responsive:

  • LAYOUT_CardDimensions: Define width y height de cada tarjeta KPI
  • LAYOUT_GridConfig: Especifica número de columnas (calculado automáticamente según ancho)
  • LAYOUT_Spacing: Controla el espaciado horizontal y vertical entre tarjetas

Resultado: Un grid que se reorganiza automáticamente según el espacio disponible.


¿Por qué funciona?

Observa cómo cada imagen muestra:

  1. Prefijos clarosUI_, LAYOUT_ — sabes inmediatamente qué hace cada señal
  2. Descripciones detalladas → Cada señal explica su propósito
  3. Objetos agrupados → Propiedades relacionadas están juntas
  4. Valores semánticos → headerTitle, kpiName, no h1, t1

Este es el resultado de aplicar la arquitectura profesional de señales desde el día 1.


💡 ¿Quieres usar este visual? El Universal KPI Trend Matrix está disponible como plantilla lista para usar en Power BI. Obtener Plantilla Premium


Beneficios Cuantificados

Sin ArquitecturaCon Arquitectura
Cambiar tema = 50+ edicionesCambiar tema = 3 ediciones
2-3 horas de trabajo2 minutos
Alto riesgo de errores0 errores
Código incomprensibleAuto-documentado

Checklist Rápido

Antes de publicar tu próximo visual, verifica:

  • Prefijos en todas las señales (UI_, DATA_, LAYOUT_, STATE_)
  • Variables agrupadas en objetos semánticos
  • description en cada señal
  • update para valores dinámicos, value para estáticos
  • Sin valores hardcodeados de ancho/alto

Conclusión

La diferencia entre un gráfico que funciona y un visual profesional está en la arquitectura:

  1. Prefijos → Revelan propósito instantáneamente
  2. Objetos → Organizan variables relacionadas
  3. Descripciones → Auto-documentan el código
  4. Reactividad → Visuales responsive automáticos

El Universal KPI Trend Matrix que viste en este artículo es prueba de que esta arquitectura funciona en producción. Cada señal tiene su lugar, cada cambio es predecible, y el código es mantenible después de meses.

Tu yo del futuro te lo agradecerá.


Recursos Relacionados

Si este artículo te resultó útil, también te recomiendo:


¿Preguntas o comentarios? Déjalos abajo en la sección de comentarios. Me encantaría saber cómo implementas estos patrones en tus propios visuales.


Por Cristobal Salcedo Beltran — Desarrollador de visuales custom con Vega y Vega-Lite en Deneb para Power BI

Fecha de publicación: 28 de enero de 2026

¿Te resultó útil este artículo?

Si este contenido te ha ayudado, considera apoyarme con un café. Tu apoyo me permite seguir creando contenido de calidad.

¡Contáctame!