K
KoreUI

Leyenda y tooltip

Chart

La leyenda son botones: al pulsarlos, ocultan la serie. El tooltip ancla la lectura al dato, no al ratón. Ninguno de los dos es decorativo — y ninguno de los dos sale por defecto.

Uso básico

Dos series con label, leyenda arriba y tooltip con crosshair. Sin <x-kore::chart.legend> ni <x-kore::chart.tooltip>, ninguno de los dos existiría: son marcas que hay que pedir, igual que los ejes — pero al contrario que los ejes, no salen por defecto.

Ingresos y gastos por mes
Categoría Gastos Ingresos
Ene 800 € 1.240 €
Feb 1.500 € 3.180 €
Mar 1.100 € 2.470 €
Abr 2.200 € 4.910 €
May 1.900 € 4.300 €
Jun 2.600 € 6.120 €
<x-kore::chart :data="$ventas" x="mes">
    <x-kore::chart.bar  y="gastos"   label="Gastos" />
    <x-kore::chart.line y="ingresos" label="Ingresos" curve="monotone" />

    <x-kore::chart.axis-y :ticks="5" format="currency" />
    <x-kore::chart.axis-x />
    <x-kore::chart.legend />
    <x-kore::chart.tooltip />
</x-kore::chart>
<x-kore::chart :data="$ventas" x="mes">
    <x-kore::chart.bar  y="gastos"   label="Gastos" />
    <x-kore::chart.line y="ingresos" label="Ingresos" curve="monotone" />

    <x-kore::chart.axis-y :ticks="5" format="currency" />
    <x-kore::chart.axis-x />
    <x-kore::chart.legend />
    <x-kore::chart.tooltip />
</x-kore::chart>

La leyenda oculta series al pulsar

Cada entrada es un <button> real, con aria-pressed — no una etiqueta. Púlsala: la serie desaparece, pero conserva su color en la paleta, y el resto no se recoloca. La identidad de una serie nunca depende solo del color: el nombre va siempre escrito al lado.

Ventas por canal
Categoría Web Tienda Móvil
Ene 600 400 240
Feb 1,4k 900 880
Mar 1,1k 700
Abr 2,2k 1,4k 1,3k
May 1,9k 1,3k 1,1k
Jun 2,9k 1,7k 1,5k

Ocultar una serie desde la leyenda no reescala los ejes. La serie desaparece, pero el eje se queda como estaba — al contrario que :show="false" puesto en el servidor, que sí saca la serie del dominio y reajusta el eje. Bajo Livewire, el estado de «oculta» lo guarda el navegador; el componente lo reaplica después de cada morph, o reaparecería en cuanto se actualizara cualquier cosa de la página.

<x-kore::chart :data="$canales" x="mes">
    <x-kore::chart.bar y="web"    label="Web"    stack="canal" />
    <x-kore::chart.bar y="tienda" label="Tienda" stack="canal" />
    <x-kore::chart.bar y="movil"  label="Móvil"  stack="canal" />

    <x-kore::chart.axis-y format="compact" />
    <x-kore::chart.axis-x />
    <x-kore::chart.legend />
    <x-kore::chart.tooltip />
</x-kore::chart>
<x-kore::chart :data="$canales" x="mes">
    <x-kore::chart.bar y="web"    label="Web"    stack="canal" />
    <x-kore::chart.bar y="tienda" label="Tienda" stack="canal" />
    <x-kore::chart.bar y="movil"  label="Móvil"  stack="canal" />

    <x-kore::chart.axis-y format="compact" />
    <x-kore::chart.axis-x />
    <x-kore::chart.legend />
    <x-kore::chart.tooltip />
</x-kore::chart>

El tooltip: crosshair y anclaje al dato

La X del tooltip se engancha al dato, no al ratón: moverte dentro de la misma banda no lo hace temblar. La Y sí sigue al cursor. El crosshair es la línea vertical que marca esa X; se apaga con :crosshair="false".

crosshair (default)

Ingresos con crosshair
Categoría Ingresos
Ene 1,2k
Feb 3,2k
Mar 2,5k
Abr 4,9k
May 4,3k
Jun 6,1k

:crosshair="false"

Ingresos sin crosshair
Categoría Ingresos
Ene 1,2k
Feb 3,2k
Mar 2,5k
Abr 4,9k
May 4,3k
Jun 6,1k

Los valores llegan ya formateados desde PHP: el JavaScript no toca un número, no sabe de monedas ni de separadores. Un null se escribe «—», no «0» — no hay dato, que no es lo mismo que valer cero (pruébalo en marzo, en el ejemplo de arriba: «Móvil» todavía no existía). Encontrar el punto bajo el ratón es una búsqueda binaria sobre las posiciones X: con 10.000 puntos son 14 comparaciones.

<x-kore::chart.tooltip />              {{-- crosshair por defecto --}}
<x-kore::chart.tooltip :crosshair="false" />
<x-kore::chart.tooltip />              {{-- crosshair por defecto --}}
<x-kore::chart.tooltip :crosshair="false" />

Ocultar el tooltip no es CSS

El payload del tooltip es una SEGUNDA copia de los datos, ya formateados, escondida en el DOM. A 2.000 puntos pesa más que el propio trazo.

show=false, condicionado desde PHP
<x-kore::chart.tooltip :show="$conTooltip" :crosshair="false" />
<x-kore::chart.tooltip :show="$conTooltip" :crosshair="false" />

:show="false" aquí NO es cosmético. No esconde el tooltip con CSS: no emite el payload. El HTML del gráfico deja de llevar una segunda copia de los valores, y el gráfico adelgaza de verdad — no solo visualmente. Es la misma prop show que apaga cualquier marca, pero en el tooltip su efecto es distinto: en una línea o una barra, show=false la oculta pero le reserva su color; en el tooltip, corta la generación del dato.

El techo son unos 2.000 puntos por serie — no lo pone el rendimiento del dibujo, lo pone el peso de ese payload. Por encima, agrega o decima los datos en PHP antes de pasarlos al gráfico.

Sin leyenda ni tooltip no hay JavaScript

El gráfico entero es SVG calculado en PHP: barras, líneas, ejes y rejilla no necesitan ni un byte de JavaScript. La leyenda y el tooltip son las DOS ÚNICAS marcas que activan comportamiento en el cliente (Alpine.js) — y por eso hay que pedirlas explícitamente, al contrario que los ejes, que salen por defecto.

Solo hace falta si usas leyenda o tooltip
<body>
    {{-- tu contenido --}}

    @livewireScripts
    @koreScripts
</body>
<body>
    {{-- tu contenido --}}

    @livewireScripts
    @koreScripts
</body>

Sin <x-kore::chart.legend> ni <x-kore::chart.tooltip> en el árbol, @koreScripts ni siquiera hace falta declararlo: la página se sirve sin cargar el bundle. El primer paint es el bueno, y con Livewire el morph actualiza el <path> sin recrear el nodo — sin wire:ignore, sin chart.update(), sin una instancia de JavaScript que proteger.

Props de legend

Prop Tipo Default Descripción
position string top top o bottom
show bool true Sin ella, la leyenda ni se registra en el gráfico

Props de tooltip

Prop Tipo Default Descripción
crosshair bool true La línea vertical que sigue al puntero, enganchada al dato
show bool true show=false no lo esconde con CSS: no emite el payload
Cargando