Component · Price Chart

Price Chart

Gráfico de línea/área informativo del precio de referencia de un activo en el tiempo. No es una herramienta de trading: sin velas, sin indicadores técnicos, sin order book, sin señales. Solo el dato neutro. El número que muestra es referencial — el precio operativo real incluye spread y comisión y se fija al confirmar.

línea/área · fl_chart sin velas · sin indicadores scrub directo draw-in 350ms · ease-standard
Anatomy

Anatomía

El encabezado comunica el qué (precio de referencia) y el cuánto cambió (variación del período). El gráfico es deliberadamente sobrio: una sola línea, un relleno tenue, ejes mínimos. Arrastra el dedo sobre la línea para ver el scrub en vivo.

Precio de referencia
· 24h
Bitcoin · 24h · variación positiva
  1. Etiqueta "Precio de referencia"

    Nunca "Precio" a secas. El ícono info abre el privacy-popover explicando que el precio final incluye spread y comisión, fijados al confirmar.

  2. Precio actual — mono tabular

    El dato más grande de la pantalla. JetBrains Mono con tabular-nums para que los dígitos no salten. Formato es-CO: $458.320.000. Sin count-up.

  3. Variación del período

    Badge success (sube) / error (baja) / neutro (plano). Flecha sutil. Se refiere solo al timeframe activo: cambiar de 24h a 1A recalcula este número.

  4. Línea de precio

    Color primary, 2dp, curva suavizada. La línea no cambia de color según la dirección — el color vive solo en el badge. Sobriedad: no pintamos todo de rojo al bajar.

  5. Relleno de área

    Degradé vertical primary → transparente, muy tenue (~16% arriba). Da volumen sin gritar. Nada de glow ni saturación.

  6. Ejes mínimos

    3–4 labels de precio (eje Y, derecha) sobre el lienzo + labels de tiempo (eje X) abajo. Línea base hairline. Sin grilla completa.

  7. Selector de timeframe

    Segmented control existente — el pill se desliza. Default 24h. Cambiar de frame redibuja la línea (draw-in) y recalcula precio + variación.

Timeframes

Selector de período

Cinco rangos: 24h · 7D · 1M · 1A · Máx. Es un segmented control (≤5 labels cortos, dentro de la regla del componente). Al cambiar: el precio de referencia y la variación se recalculan para ese rango, y la línea hace draw-in. Pruébalo — toca los segmentos.

InteractivoCambia de frame y observa el redibujo
Precio de referencia
ReglasComportamiento del selector
· Default 24h al abrir cualquier activo.
· La variación siempre corresponde al frame activo (24h → cambio de 24h; 1A → cambio de 12 meses).
· Máx = desde que MiCapi lista el activo / dato disponible más antiguo.
· El frame elegido no se persiste entre activos: cada pantalla abre en 24h.
· Haptic selectionClick() al cambiar de segmento.
· Las labels del eje X se adaptan al frame: horas (24h), días (7D/1M), meses (1A/Máx).
Scrub interaction

Lectura por arrastre

Tocar y arrastrar sobre el gráfico revela el precio histórico de cada punto: línea guía vertical hairline + punto sobre la línea, y el encabezado se sincroniza — el precio mono muestra el valor del punto y la etiqueta «Precio de referencia» se reemplaza por su fecha/hora. Sin caja flotante; nada ocluye la línea. Al soltar, snap de vuelta al precio actual. Es para leer el histórico, no para operar.

Precio de referencia
· 24h
Arrastra el dedo · tooltip en vivo
  1. Punto y línea guía

    Un punto primary con halo blanco se ancla sobre la línea en el dato más cercano al dedo. Una guía vertical hairline cae desde el punto. Sin grilla extra, sin caja flotante.

  2. El encabezado se sincroniza

    El precio grande (mono) se reescribe al valor del punto y la etiqueta «Precio de referencia» se reemplaza por la fecha/hora de ese dato. El ojo no se mueve y nada ocluye la línea.

  3. Sin caja flotante

    Descartamos el tooltip-burbuja sobre el punto: en pantallas pequeñas tapa la línea justo bajo el dedo. Toda la lectura vive en el encabezado, que ya es el ancla visual de la pantalla.

  4. Soltar = volver al presente

    Al levantar el dedo, el punto y la guía se desvanecen (duration-fast) y el encabezado hace snap de vuelta al precio actual del frame + variación del período.

Decisión tomada

Header sincronizado (Opción B)

El valor escrubeado se lee en el encabezado: el precio mono se reescribe al punto y la etiqueta se vuelve su fecha/hora. Nada flota sobre la línea. Es el patrón más calmado y «no-trading». La Opción A queda registrada como alternativa considerada.

B · Header se sincronizaElegida

El precio grande del encabezado se reescribe al valor del punto mientras arrastras y la etiqueta «Precio de referencia» se reemplaza por la fecha/hora. El ojo no se mueve, nada ocluye la línea. Al soltar, snap al precio actual + variación del período.

A · Tooltip flotanteAlternativa considerada

Burbuja sobre el punto con precio + fecha. Reconocible, pero puede tapar la línea bajo el dedo en pantallas pequeñas. Descartada como variante viva.

States

Estados

El gráfico conserva su altura en todos los estados — la pantalla nunca salta. Loading usa el chart skeleton (shimmer) ya definido; el encabezado de precio también es skeleton para no mentir un número mientras carga.

aVariación positiva
Precio de referencia
· 24h
Badge success. La línea es del mismo color que en el caso negativo.
bVariación negativa
Precio de referencia
· 24h
Badge error. Misma línea verde — no se pinta de rojo. Solo el badge cambia.
cCargando · skeleton
Chart skeleton (shimmer 1500ms) + precio skeleton. Crossfade a real al llegar data.
dError de carga
No pudimos cargar el precio
El bloque mantiene la altura del gráfico. Mensaje neutro + acción única. Sin números falsos.
eCasi plano · USDT
Precio de referencia · USDT
· 24h
Stablecoin: el gráfico es casi recto y está bien así. No forzamos volatilidad visual.
Caso USDT · depeg

Stablecoin — paridad y riesgo

USDT sigue esencialmente la tasa del dólar (TRM), no la volatilidad cripto: su línea en COP es casi recta. Comunicamos qué busca hacer (paridad con el dólar) y el riesgo de que no lo logre (depeg). Nunca afirmamos "USDT = 1 USD" ni paridad garantizada.

Precio de referencia
· 24h
USDT busca mantener paridad con el dólar estadounidense.
Riesgo de desviación de paridad (depeg) El valor de las stablecoins puede desviarse de su paridad. MiCapi no garantiza la convertibilidad 1:1 con el dólar.
Tether · USDT · 24h · variación ~0%
  1. Variación neutra, no plana de mentira

    La variación rondará 0% (badge neutro, ícono minus). Mostramos el dato real aunque sea pequeño; no lo redondeamos a 0,0% si no lo es.

  2. Etiqueta de paridad

    "USDT busca mantener paridad con el dólar estadounidense." Verbo busca, nunca es ni equivale a. El acento usa el verde de marca de USDT.

  3. Alert de depeg — siempre visible

    Alert warning bajo el gráfico. No es descartable en el detalle del activo: es información de riesgo, no una notificación.

  4. Escala sensible

    El eje Y se ajusta a un rango estrecho para que las micro-variaciones de la TRM se lean, pero sin exagerar la amplitud (nada de zoom dramático que simule volatilidad).

Motion

Movimiento

El movimiento es funcional y sobrio. Tres reglas; nada más.

01Draw-in · wipe
Precio de referencia
· 24h
La línea se revela de izquierda a derecha (wipe): duration-slow 350ms + ease-standard. Toca para repetir.
02Scrub directo
El punto = el dedo.
Sin delay, sin easing, tracking 1:1.
Animar la posición del scrub haría sentir el gráfico "atascado". El punto sigue al dedo instantáneamente.
03Sin count-up
$458.320.000
nada de 0 → 458M animado
El precio aparece en su valor final. Animar dinero con count-up sugiere "movimiento/ganancia": prohibido.
Reduced motion

Respetar MediaQuery.disableAnimationsOf(context)

Con reduced motion activo: la línea aparece estática y completa (sin wipe), el shimmer del skeleton se reemplaza por un pulso de opacidad, y el scrub sigue funcionando igual (nunca dependió de animación). Esta página respeta prefers-reduced-motion en tu sistema.

Dark mode

Modo oscuro

En dark la línea usa primary-300 (#27A89C) para sostener contraste sobre bg-elevated. El relleno baja su alpha. Labels de eje en fg-subtle. El tooltip se oscurece aún más para destacar.

Dark · BTC (positiva) · USDT (depeg) · Loading
Bitcoindark · scrub on
9:41
₿
Bitcoin
Precio de referencia
· 24h
Tetherdark · depeg
9:41
Tether
Precio de referencia
· 24h
USDT busca mantener paridad con el dólar estadounidense.
Riesgo de depeg El valor puede desviarse de su paridad. MiCapi no garantiza convertibilidad 1:1.
Cargandodark · skeleton
9:41
₿
Bitcoin
Flutter notes

Implementación

El render real es fl_chart · LineChart. Esta página simula el comportamiento en SVG, pero las decisiones de diseño se mapean 1:1 a la API del paquete.

fl_chart · LineChart

Una sola LineChartBarData. Sin candlesticks (fl_chart no los trae y es deliberado). El scrub usa el touchCallback nativo del paquete; el draw-in se hace animando el factor de recorte de la barra.

Línea + área

isCurved: true, curveSmoothness: 0.28, barWidth: 2, color: primary500. Área: BelowBarData(show:true) con LinearGradient vertical primary @ 0.16 → transparent. dotData: FlDotData(show:false) salvo el punto de scrub.

Ejes

gridData: FlGridData(show:false) (solo línea base via borderData inferior). leftTitles/rightTitles: 3–4 labels en mono. bottomTitles: tiempo según frame. Reservar el alto para que el cambio de estado no salte.

Scrub · touch

lineTouchData: LineTouchData con getTouchedSpotIndicator para la guía vertical + punto. Sin tooltip incorporado (touchTooltipData → getTooltipItems vacío); en su lugar, touchCallback sincroniza el estado del encabezado (precio + fecha) y al soltar restaura el precio actual + variación del período.

Draw-in + reduced motion

Animar un AnimationController (350ms, Curves.fastOutSlowIn) que recorta la barra (ClipRect + Align widthFactor) de izq→der. Si MediaQuery.disableAnimationsOf(context) → pintar completo sin animar. Nunca animar el texto del precio.

// Línea de precio — sobria, informativa (no trading)
LineChartBarData(
  spots: spots,                       // List<FlSpot> del frame activo
  isCurved: true, curveSmoothness: 0.28,
  color: MiCapi.primary500,    // la línea NO cambia por dirección
  barWidth: 2, isStrokeCapRound: true,
  dotData: const FlDotData(show: false),
  belowBarData: BarAreaData(
    show: true,
    gradient: LinearGradient(
      begin: Alignment.topCenter, end: Alignment.bottomCenter,
      colors: [MiCapi.primary500.withOpacity(0.16), Colors.transparent],
    ),
  ),
)