Skip to content

Series y gráficas

This content is not available in your language yet.

Una serie es una lista de valores con marcas de tiempo. Desde un artefacto se alimenta con pushData y se grafica con plotSerie.

pushData("temperaturas", 23.5);

pushData agrega el valor y su marca de tiempo (el reloj del navegador en ese instante), manteniendo alineadas temperaturas y temperaturas_time. Es el único camino correcto para alimentar una serie desde un artefacto.

El caso típico es registrar algo que hace el usuario:

document.querySelector("#btn").addEventListener("click", () => pushData("eventos", 1));
gVar.temperaturas = []; // borra valores y tiempos

Es la única asignación de arreglo permitida sobre una serie. Asignar un arreglo con valores lanza TypeError.

Varias pestañas del mismo artefacto pueden estar abiertas a la vez, y dos flujos de pushData sobre la misma serie la desordenarían. Por eso las operaciones de serie (pushData y el reinicio) necesitan un rol de escritura por variable:

  • El runtime lo pide solo, la primera vez que tu código toca esa serie.
  • Si otra pestaña lo tiene, tu pushData avisa por console.warn y no escribe.
  • Puedes tomarlo a la fuerza: await requestWriter("temperaturas", { force: true }).
  • Puedes soltarlo: await releaseWriter("temperaturas").

Ambas funciones devuelven una promesa con true o false. El estado vive en gVarStatus.writer:

gVarStatus.writer.keys; // series que controlo yo
gVarStatus.writer.forced; // ...tomadas a la fuerza
gVarStatus.writer.claimed; // todas las series con dueño ahora mismo

Los escalares no usan rol: la última escritura gana.

const proj = plotSerie("temperaturas", {
maxPoints: 100, // cuántos puntos recientes incluir (def. 100)
timeMode: "clock", // cómo construir el eje X
});
// proj.points = [{ x: 0, label: "12:30:01", y: 23.5 }, { x: 1, label: "12:30:02", y: 23.6 }, ...]

plotSerie es síncrona y devuelve null si la serie no tiene datos: comprueba eso antes de dibujar. Además de points, devuelve values, timestamps, originTimestamp, totalLength, hasTimestamps y timeMode.

Cada punto tiene tres campos:

  • x — índice dentro de la ventana proyectada (0, 1, 2…): posición equiespaciada.
  • label — string para el eje X (según timeMode: "12:30:01", "1.5", "0"…).
  • y — valor numérico, o null si el valor no es numérico.
ModoEje X
clockHora del reloj ("12:30:01").
relative-msMilisegundos desde el inicio de la serie.
relative-secondsSegundos desde el inicio.
relative-minutesMinutos desde el inicio.

No hay callbacks de actualización: se proyecta y se dibuja en el mismo intervalo con el que la plataforma sincroniza.

function dibujar(labels, data) {
// entrega labels (eje X) y data (valores) a tu librería o canvas
}
setInterval(() => {
const proj = plotSerie("temperaturas", { maxPoints: 100, timeMode: "clock" });
if (!proj) return;
const labels = proj.points.map((p) => p.label); // "12:30:01", "12:30:02"...
const data = proj.points.map((p) => p.y); // 23.5, 23.6...
dibujar(labels, data);
}, 500);

Con Chart.js, actualiza sin animación para que no parpadee:

setInterval(() => {
const proj = plotSerie("temperaturas", { maxPoints: 100, timeMode: "clock" });
if (!proj) return;
miChart.data.labels = proj.points.map((p) => p.label);
miChart.data.datasets[0].data = proj.points.map((p) => p.y);
miChart.update("none");
}, 500);