Creación de gráficos en tiempo real con GraphQL y Postgres

 

 

 

  • ¡Registro!

  • Índice
    1. Pila
    2. Requisitos
    3. Manifestación
  • Configurando el backend
    1. Ejecutando los servicios
    2. Configurando la base de datos
  • Interfaz
    1. Hola, suscripciones a GraphQL
    2. Comenzando con la aplicación Create-React
    3. Configuración del cliente Apollo para GraphQL del lado del cliente
    4. Construyendo el gráfico
    5. Insertar datos de muestra
  • Terminando
  • No hay mejor manera de comprender los datos que visualizándolos con gráficos y diagramas. La comunidad JS tiene algunos grandes proyectos de código abierto que facilitan la visualización de datos; sin embargo, no ha habido una solución para crear backends en tiempo real que puedan respaldar estos gráficos y convertirlos en tiempo real. Con GraphQL (que tiene una especificación bien definida para suscripciones en tiempo real), podemos ejecutar un backend en tiempo real en segundos y usarlo para impulsar gráficos en tiempo real.

     

    Los gráficos forman una parte integral de cualquier industria que se ocupe de datos. Los gráficos son útiles en la industria de la votación y las encuestas, y también son excelentes para ayudarnos a comprender mejor los diferentes comportamientos y características de los usuarios y clientes con los que trabajamos.

    ¿Por qué son tan importantes los gráficos en tiempo real? Bueno, son útiles en los casos en que se producen nuevos datos continuamente; por ejemplo, cuando el uso de series en tiempo real para visualizar los precios de las acciones es un gran uso para los gráficos en tiempo real. En este tutorial, explicaré cómo crear gráficos en tiempo real con tecnologías de código abierto aptas exactamente para esta tarea en particular.

    Nota : este tutorial requiere conocimientos básicos de React y GraphQL.

    Pila

    1. PostgreSQL
      El objetivo fundamental del uso de gráficos es visualizar volúmenes "enormes" de datos. Por lo tanto, necesitamos una base de datos que maneje de manera eficiente grandes datos y proporcione una API intuitiva para reestructurarlos. Las bases de datos SQL nos permiten crear vistas que abstraen y agregan datos por nosotros. Usaremos Postgres, que es una base de datos altamente eficiente y probada en el tiempo . También tiene sofisticadas extensiones de código abierto como Timescale y PostGIS que nos permiten crear gráficos basados ​​en geolocalización y series de tiempo, respectivamente. Usaremos Timescale para construir nuestro gráfico de series de tiempo.
    2. Motor GraphQL
      Esta publicación trata sobre la creación de gráficos en tiempo real y GraphQL viene con una especificación bien definida para suscripciones en tiempo real. Hasura GraphQL Engine es un servidor GraphQL de código abierto que toma una conexión Postgres y le permite consultar los datos de Postgres a través de GraphQL en tiempo real. También viene con una capa de control de acceso que le ayuda a restringir sus datos según reglas de control de acceso personalizadas.
    3. ChartJS
      ChartJS es una biblioteca de código abierto popular y bien mantenida para crear gráficos con JavaScript. Lo usaremos chart.jsjunto con su abstracción ReactJS react-chartjs-2. El motivo de React es que React brinda a los desarrolladores una API intuitiva basada en eventos. Además, el flujo de datos unidireccional de React es ideal para crear gráficos basados ​​en datos.

    Requisitos

    Para este tutorial, necesitará lo siguiente en su sistema:

    1. Docker CE
      Docker es un software que le permite contener sus aplicaciones. Una imagen de Docker es un paquete independiente que contiene software junto con sus dependencias y un sistema operativo minimalista. Técnicamente, estas imágenes de Docker se pueden ejecutar en cualquier máquina que tenga Docker instalado. Necesitará Docker para este tutorial.
      • Leer más sobre Docker
      • Instalar ventana acoplable
    2. npm : npm es el paquete de administración para JavaScript.

    Manifestación

    Construiremos el siguiente gráfico de series de tiempo en vivo que muestra la temperatura máxima de una ubicación en intervalos de 5 segundos durante los últimos 20 minutos desde el momento actual.

    Configurando el backend

    Ejecutando los servicios

    El backend se compone de una base de datos Postgres, su extensión de escala de tiempo y Hasura GraphQL Engine. Ejecutemos la base de datos y nuestro servidor GraphQL ejecutando las respectivas imágenes de la ventana acoplable. Cree un archivo llamado docker-compose.yamly pegue este contenido en él.

    Nota : docker-compose es una utilidad para ejecutar varias imágenes acoplables de forma declarativa.

    version: '2'services: timescale: image: timescale/timescaledb:latest-pg10 restart: always environment: POSTGRES_PASSWORD: postgrespassword volumes: - db_data:/var/lib/postgresql/data graphql-engine: image: hasura/graphql-engine:v1.0.0-alpha38 ports: - "8080:8080" depends_on: - "timescale" restart: always environment: HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@timescale:5432/postgres HASURA_GRAPHQL_ACCESS_KEY: mylongsecretkey command: - graphql-engine - serve - --enable-consolevolumes: db_data:

    Este docker-compose.yamlcontiene las especificaciones para dos servicios:

    1. timescale
      Esta es nuestra base de datos Postgres con la extensión Timescale instalada. Está configurado para ejecutarse en el puerto 5432.
    2. graphql-engine
      Esta es nuestra instancia de Hasura GraphQL Engine, es decir, el servidor GraphQL que apunta a la base de datos y proporciona API GraphQL sobre ella. Está configurado para ejecutarse en el puerto 8080 y el puerto 8080 está asignado al puerto 8080 de la máquina en la que se ejecuta este contenedor acoplable. Esto significa que puede acceder a este servidor GraphQL a través localhost:8080de la máquina.

    Ejecutemos estos contenedores acoplables ejecutando el siguiente comando dondequiera que haya colocado su archivo docker-compose.yaml.

    docker-compose up -d

    Este comando extrae las imágenes de la ventana acoplable de la nube y las ejecuta en el orden indicado. Es posible que tarde unos segundos según su velocidad de Internet. Una vez que esté completo, podrá acceder a su consola GraphQL Engine en https://localhost:8080/console.

     

    Consola Hasura GraphQL Engine ( vista previa grande )

    Configurando la base de datos

    A continuación, creemos una tabla llamada temperatura que almacena los valores de temperaturas en diferentes momentos. Vaya a la pestaña Datos en la consola y vaya a la SQLsección. Cree nuestra temperaturetabla ejecutando este bloque SQL:

    CREATE TABLE temperature ( temperature numeric not null, location text not null, recorded_at timestamptz not null default now());

    Esto crea una tabla de Postgres simple en la base de datos. Pero deseamos aprovechar la partición del intervalo de tiempo de la extensión Timescale. Para hacer esto, debemos convertir esta tabla en una hipertabla de escala de tiempo ejecutando el comando SQL:

    SELECT create_hypertable('temperature', 'recorded_at');

    Este comando crea una hipertabla dividida por tiempo en el campo recorded_at.

    Ahora, una vez creada esta tabla, podemos comenzar directamente a realizar consultas GraphQL sobre ella. Puedes probarlos haciendo clic en la GraphiQLpestaña en la parte superior. Intente hacer una mutación primero:

    mutation { insert_temperature ( objects: [{ temperature: 13.4 location: "London" }] ) { returning { recorded_at temperature } }}

    La mutación GraphQL anterior inserta una fila en la temperaturetabla. Ahora intente realizar una consulta GraphQL para verificar si se insertaron los datos.

    Entonces intenta hacer una consulta:

    query { temperature { recorded_at temperature location }}

    Espero que haya funcionado 🙂

    Ahora, la tarea que tenemos entre manos es crear un gráfico de series temporales en vivo que muestre la temperatura máxima de una ubicación en intervalos de 5 segundos durante los últimos 20 minutos desde el momento actual. Creemos una vista que nos proporcione exactamente estos datos.

    CREATE VIEW last_20_min_temp AS ( SELECT time_bucket('5 seconds', recorded_at) AS five_sec_interval, location, MAX(temperature) AS max_temp FROM temperature WHERE recorded_at NOW() - interval '20 minutes' GROUP BY five_sec_interval, location ORDER BY five_sec_interval ASC);

    Esta vista agrupa los datos de la temperaturetabla en ventanas de 5 segundos con su temperatura máxima ( max_temp). La agrupación secundaria se realiza usando el locationcampo. Todos estos datos son solo de los últimos veinte minutos desde el momento actual.

    Eso es todo. Nuestro backend está configurado. Construyamos ahora un bonito gráfico en tiempo real.

    Interfaz

    Hola, suscripciones a GraphQL

    Las suscripciones a GraphQL son esencialmente consultas GraphQL "en vivo". Operan sobre WebSockets y tienen exactamente la misma estructura de respuesta que las consultas GraphQL. Vuelva https://localhost:8080/consolee intente realizar una suscripción GraphQL a la vista que creamos. Cómo Localizar un Celular Móvil [ Contenido Actualizado Diciembre del 2024 ]

    subscription { last_20_min_temp( order_by: { five_sec_interval: asc } where: { location: { _eq: "London" } } ) { five_sec_interval location max_temp }}

    Esta suscripción suscribe los datos de la vista donde está la ubicación Londony está ordenado en orden ascendente del five_second_intervals.

     

    Naturalmente, la respuesta de la vista sería una matriz vacía porque no hemos insertado nada en la base de datos en los últimos veinte minutos. (Es posible que vea la entrada que insertamos hace algún tiempo si llegó a esta sección dentro de veinte minutos).

    { "data": { "last_20_min_temp": [] }}

    Manteniendo esta suscripción activada, abra otra pestaña e intente insertar otro valor en la temperaturestabla usando la misma mutación que realizamos anteriormente. Después de insertar, si regresa a la pestaña donde estaba la suscripción, verá que la respuesta se actualizó automáticamente. Esa es la magia en tiempo real que proporciona GraphQL Engine. Utilicemos esta suscripción para potenciar nuestro gráfico en tiempo real.

    Comenzando con la aplicación Create-React

    Comencemos rápidamente con un iniciador de aplicación React usando crear aplicación de reacción . Ejecute el comando:

    npx create-react-app time-series-chart

    Esto creará un proyecto inicial vacío. cden él e instale GraphQL y las bibliotecas de gráficos. Además, instale Moment para convertir marcas de tiempo a un formato legible por humanos.

    cd time-series-chartnpm install --save apollo-boost apollo-link-ws subscriptions-transport-ws graphql react-apollo chart.js react-chartjs-2 moment

    Finalmente, ejecute la aplicación npm starty se abrirá una aplicación React básica en https://localhost:3000.

    Aplicación raw creat-react ( vista previa grande )

    Configuración del cliente Apollo para GraphQL del lado del cliente

    El cliente Apollo es actualmente el mejor cliente GraphQL que funciona con cualquier servidor compatible con GraphQL. Relay Modern también es bueno, pero el servidor debe admitir la especificación de Relay para aprovechar todos los beneficios de Relay Modern. Usaremos el cliente Apollo para GraphQL del lado del cliente para este tutorial. Realicemos la configuración para proporcionar el cliente Apollo a la aplicación.

    No voy a entrar en las sutilezas de esta configuración porque los siguientes fragmentos de código se han tomado directamente de los documentos . Dirígete src/index.jsal directorio de la aplicación React, crea una instancia del cliente Apollo y agrega este fragmento de código arriba ReactDOM.render.

    import { WebSocketLink } from 'apollo-link-ws';import { ApolloClient } from 'apollo-client';import { ApolloProvider } from 'react-apollo';import { InMemoryCache } from 'apollo-cache-inmemory';// Create a WebSocket link:const link = new WebSocketLink({ uri: `ws://localhost:8080/v1alpha1/graphql`, options: { reconnect: true, connectionParams: { headers: { "x-hasura-admin-secret: "mylongsecretkey" } } }})const cache = new InMemoryCache();const client = new ApolloClient({ link, cache});

    Finalmente, envuelva el Appinterior ApolloProviderpara que podamos usar el cliente Apollo en los componentes secundarios. Finalmente deberías App.jslucir así:

     

    import React from 'react';import ReactDOM from 'react-dom';import './index.css';import App from './App';import { WebSocketLink } from 'apollo-link-ws';import { ApolloClient } from 'apollo-client';import { ApolloProvider } from 'react-apollo';import { InMemoryCache } from 'apollo-cache-inmemory';// Create a WebSocket link:const link = new WebSocketLink({ uri: `ws://localhost:8080/v1alpha1/graphql`, options: { reconnect: true, connectionParams: { headers: { "x-hasura-admin-secret: "mylongsecretkey" } } }})const cache = new InMemoryCache();const client = new ApolloClient({ link, cache});ReactDOM.render( ( ApolloProvider client={client} App / /ApolloProvider ), document.getElementById('root'));

    El cliente Apollo ha sido configurado. Ahora podemos usar fácilmente GraphQL en tiempo real desde nuestra aplicación. Dirigirse a src/App.js.

    Construyendo el gráfico

    ChartJS proporciona una API bastante interesante para crear gráficos. Construiremos un gráfico de líneas; entonces un gráfico de líneas espera datos de la forma:

    { "labels": ["label1", "label2", "label3", "label4"], "datasets": [{ "label": "Sample dataset", "data": [45, 23, 56, 55], "pointBackgroundColor": ["red", "brown", "green", "yellow"], "borderColor": "brown", "fill": false }],}

    Si el conjunto de datos anterior se utiliza para representar un gráfico de líneas, se vería así:

    Gráfico de líneas de muestra ( vista previa grande )

    Intentemos construir este gráfico de muestra primero. Importarlo Liney react-chartjs-2renderizarlo pasando el objeto anterior como un accesorio de datos. El método de renderizado se vería así:

    render() { const data = { "labels": ["label1", "label2", "label3", "label4"], "datasets": [{ "label": "Sample dataset", "data": [45, 23, 56, 55], "pointBackgroundColor": ["red", "brown", "green", "yellow"], "borderColor": "brown", "fill": false }], } return ( div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '20px'}} Line data={data} / /div );}

    A continuación, nos suscribiremos a los datos de nuestra vista y los introduciremos en el gráfico de líneas. Pero, ¿cómo realizamos suscripciones en el cliente?

    SubscriptionLos componentes de Apollo funcionan utilizando el patrón de representación donde los hijos de un componente se representan con el contexto de los datos de suscripción.

    Subscription subscription={gql`subscription { parent { child } }`}/ { ({data, error, loading}) = { if (error) return Error error={error} /; if (loading) return Loading /; return RenderData data={data} /; } }/Subscription

    Usemos uno de esos Subscriptioncomponentes para suscribirnos a nuestra vista y luego transformemos los datos de suscripción a la estructura que espera ChartJS. La lógica transformadora se ve así:

    let chartJSData = { labels: [], datasets: [{ label: "Max temperature every five seconds", data: [], pointBackgroundColor: [], borderColor: 'brown', fill: false }]};data.last_20_min_temp.forEach((item) = { const humanReadableTime = moment(item.five_sec_interval).format('LTS'); chartJSData.labels.push(humanReadableTime); chartJSData.datasets[0].data.push(item.max_temp); chartJSData.datasets[0].pointBackgroundColor.push('brown');})

    Nota : También puede utilizar la biblioteca de código abierto graphq2chartjs para transformar los datos de la respuesta GraphQL a una forma que ChartJS espera.

     

    Después de usar esto dentro del componente Suscripción, nuestro App.jsaspecto es el siguiente:

    import React, { Component } from 'react';import { Line } from 'react-chartjs-2';import { Subscription } from 'react-apollo';import gql from 'graphql-tag';import moment from 'moment';const TWENTY_MIN_TEMP_SUBSCRIPTION= gql' subscription { last_20_min_temp( order_by: { five_sec_interval: asc } where: { location: { _eq: "London" } } ) { five_sec_interval location max_temp } }'class App extends Component { render() { return ( div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '20px'}} Subscription subscription={TWENTY_MIN_TEMP_SUBSCRIPTION} { ({data, error, loading}) = { if (error) { console.error(error); return "Error"; } if (loading) { return "Loading"; } let chartJSData = { labels: [], datasets: [{ label: "Max temperature every five seconds", data: [], pointBackgroundColor: [], borderColor: 'brown', fill: false }] }; data.last_20_min_temp.forEach((item) = { const humanReadableTime = moment(item.five_sec_interval).format('LTS'); chartJSData.labels.push(humanReadableTime); chartJSData.datasets[0].data.push(item.max_temp); chartJSData.datasets[0].pointBackgroundColor.push('brown'); }) return ( Line data={chartJSData} options={{ animation: {duration: 0}, scales: { yAxes: [{ticks: { min: 5, max: 20 }}]} }} / ); } } /Subscription /div ); }}export default App;

    Tendrá listo un gráfico en tiempo real completamente funcional en https://localhost:3000. Sin embargo, estaría vacío, así que completemos algunos datos de muestra para que podamos ver cómo sucede algo de magia.

    Nota : Agregué algunas opciones más al gráfico de líneas porque no me gustan esas animaciones sofisticadas en ChartJS. Una serie temporal parece atractiva cuando es simple; sin embargo, puedes eliminar el accesorio de opciones si lo deseas.

    Insertar datos de muestra

    Escribamos un script que complete nuestra base de datos con datos ficticios. Cree un directorio separado (fuera de esta aplicación) y cree un archivo llamado script.jscon el siguiente contenido,

    const fetch = require('node-fetch');setInterval( () = { const randomTemp = (Math.random() * 5) + 10; fetch( `https://localhost:8080/v1alpha1/graphql`, { method: 'POST', body: JSON.stringify({ query: ` mutation ($temp: numeric) { insert_temperature ( objects: [{ temperature: $temp location: "London" }] ) { returning { recorded_at temperature } } } `, variables: { temp: randomTemp } }) } ).then((resp) = resp.json().then((respObj) = console.log(JSON.stringify(respObj, null, 2)))); }, 2000);

    Ahora ejecute estos dos comandos:

    npm install --save node-fetchnode script.js

    Puede volver https://localhost:3000y ver la actualización del gráfico.

    Terminando

    Puede crear la mayoría de los gráficos en tiempo real utilizando las ideas que analizamos anteriormente. El algoritmo es:

    1. Implementar el motor GraphQL con Postgres;
    2. Cree tablas donde desee almacenar datos;
    3. Suscríbete a esas tablas desde tu aplicación React;
    4. Representa el gráfico.

    Puedes encontrar el código fuente aquí .

    (dm, ra, il)Explora más en

    • javascript
    • GrafoQL
    • Visualizaciones





    Tal vez te puede interesar:

    1. Creación de su propia biblioteca de validación de React: la experiencia del desarrollador (Parte 3)
    2. Introducción a Quasar Framework: creación de aplicaciones multiplataforma
    3. Creación de un componente web retro que se puede arrastrar con iluminación
    4. Creación y acoplamiento de una aplicación Node.js con arquitectura sin estado con la ayuda de Kinsta

    Creación de gráficos en tiempo real con GraphQL y Postgres

    Creación de gráficos en tiempo real con GraphQL y Postgres

    PilaRequisitosManifestaciónEjecutando los serviciosConfigurando la base de datosHola, suscripciones a GraphQLComenzando con la aplicación Create-ReactConfigu

    programar

    es

    https://aprendeprogramando.es/static/images/programar-creacion-de-graficos-en-tiempo-real-con-graphql-y-postgres-976-0.jpg

    2024-12-03

     

    Creación de gráficos en tiempo real con GraphQL y Postgres
    Creación de gráficos en tiempo real con GraphQL y Postgres

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Update cookies preferences