Índice
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
- 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. - 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. - ChartJS
ChartJS es una biblioteca de código abierto popular y bien mantenida para crear gráficos con JavaScript. Lo usaremoschart.js
junto con su abstracción ReactJSreact-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:
- 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
- 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.yaml
y 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.yaml
contiene las especificaciones para dos servicios:
timescale
Esta es nuestra base de datos Postgres con la extensión Timescale instalada. Está configurado para ejecutarse en el puerto 5432.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éslocalhost:8080
de 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
.
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 SQL
sección. Cree nuestra temperature
tabla 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 GraphiQL
pestañ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 temperature
tabla. 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 temperature
tabla en ventanas de 5 segundos con su temperatura máxima ( max_temp)
. La agrupación secundaria se realiza usando el location
campo. 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/console
e 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 London
y 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 temperatures
tabla 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. cd
en é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 start
y se abrirá una aplicación React básica en https://localhost:3000
.
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.js
al 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 App
interior ApolloProvider
para que podamos usar el cliente Apollo en los componentes secundarios. Finalmente deberías App.js
lucir 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í:
Intentemos construir este gráfico de muestra primero. Importarlo Line
y react-chartjs-2
renderizarlo 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?
Subscription
Los 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 Subscription
componentes 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.js
aspecto 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.js
con 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:3000
y 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:
- Implementar el motor GraphQL con Postgres;
- Cree tablas donde desee almacenar datos;
- Suscríbete a esas tablas desde tu aplicación React;
- 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:
- Creación de su propia biblioteca de validación de React: la experiencia del desarrollador (Parte 3)
- Introducción a Quasar Framework: creación de aplicaciones multiplataforma
- Creación de un componente web retro que se puede arrastrar con iluminación
- 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
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
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