Java, UX, HTML, CSS, WEB-design

Построение диаграмм в реальном времени с помощью GraphQL и Postgres

Краткое описание по статье Построение диаграмм в реальном времени с помощью GraphQL и Postgres

Название: Построение диаграмм в реальном времени с помощью GraphQL и Postgres . Краткое описание: ⭐ Ришичандра . Дата публикации: 24.01.2022 . Автор: Алишер Валеев .

Для чего создан сайт Novosti-Nedeli.ru

Данный сайт посвящен новостям мира и мира технологий . Также тут вы найдете руководства по различным девайсам.

Сколько лет сайту?

Возраст составляет 3 года


  • Ришичандра Вавал

  • 0 Комментарии

Построение диаграмм в реальном времени с помощью GraphQL и Postgres

  • 12 минут чтения

  • JavaScript, GraphQL, визуализации

Краткое резюме ↬

Нет лучшего способа понять данные, чем визуализировать их с помощью диаграмм и диаграмм. В сообществе JS есть несколько отличных проектов с открытым исходным кодом, которые упрощают визуализацию данных, однако не существует готового решения для создания серверных частей в реальном времени, которые могли бы поддерживать эти диаграммы и делать их в реальном времени. С GraphQL (у которого есть четко определенная спецификация для подписок в реальном времени) мы можем запустить серверную часть в реальном времени за считанные секунды и использовать ее для построения графиков в реальном времени.

Диаграммы являются неотъемлемой частью любой отрасли, которая имеет дело с данными. Диаграммы полезны в индустрии голосования и опросов, а также отлично помогают нам лучше понять различное поведение и характеристики пользователей и клиентов, с которыми мы работаем.

Почему графики в реальном времени так важны? Что ж, они полезны в тех случаях, когда новые данные создаются непрерывно; например, при использовании динамических рядов для визуализации цен на акции отлично подходят графики в реальном времени. В этом уроке я объясню, как создавать графики в реальном времени с помощью технологий с открытым исходным кодом, подходящих именно для этой конкретной задачи.

Примечание: Для этого руководства требуются базовые знания React и GraphQL.

Куча

  1. PostgreSQL
    Сам смысл использования диаграмм заключается в визуализации «огромных» объемов данных. Поэтому нам нужна база данных, которая эффективно обрабатывает большие данные и предоставляет интуитивно понятный API для их реструктуризации. Базы данных SQL позволяют нам создавать представления, которые абстрагируют и объединяют данные для нас. Мы будем использовать Postgres, проверенную временем и высокоэффективную базу данных. Он также имеет причудливые расширения с открытым исходным кодом, такие как Timescale и PostGIS, которые позволяют нам строить диаграммы на основе геолокации и временных рядов соответственно. Мы будем использовать шкалу времени для построения диаграммы временных рядов.
  2. Графический движок QL
    Этот пост посвящен построению диаграмм в реальном времени, а GraphQL поставляется с четко определенной спецификацией для подписки в реальном времени. Hasura GraphQL Engine — это сервер GraphQL с открытым исходным кодом, который принимает соединение Postgres и позволяет запрашивать данные Postgres через GraphQL в реальном времени. Он также поставляется с уровнем контроля доступа, который помогает вам ограничивать ваши данные на основе настраиваемых правил контроля доступа.
  3. ЧартJS
    ChartJS — популярная и хорошо поддерживаемая библиотека с открытым исходным кодом для построения диаграмм с помощью JavaScript. Мы будем использовать chart.js вместе с его абстракцией ReactJS react-chartjs-2. О том, почему React, потому что React предоставляет разработчикам интуитивно понятный API, управляемый событиями. Кроме того, однонаправленный поток данных React идеально подходит для построения диаграмм, управляемых данными.

Еще после прыжка! Продолжить чтение ниже ↓

Требования

Для этого руководства вам потребуется следующее в вашей системе:

  1. Докер СЕ
    Docker — это программное обеспечение, которое позволяет вам контейнеризовать ваши приложения. Docker-образ — это независимый пакет, содержащий программное обеспечение вместе с его зависимостями и минималистичной операционной системой. Такие образы докеров технически можно запускать на любой машине, на которой установлен докер. Для этого урока вам понадобится докер.
    • Подробнее о Докере
    • Установить Докер
  2. npm: npm — это управление пакетами для JavaScript.

Демо

Мы построим следующую диаграмму временных рядов в реальном времени, которая показывает максимальную температуру местоположения с интервалом в 5 секунд за последние 20 минут с настоящего момента.

GIF-демонстрация диаграммы в реальном времени
GIF-демонстрация диаграммы в реальном времени

Настройка бэкенда

Запуск служб

Серверная часть состоит из базы данных Postgres, расширения временной шкалы и Hasura GraphQL Engine. Давайте запустим базу данных и наш сервер GraphQL, запустив соответствующие образы докеров. Создайте файл с именем docker-compose.yaml и вставьте в него это содержимое.

Примечание: docker-compose — это утилита для декларативного запуска нескольких образов Docker.

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-console
volumes:
  db_data:

Этот docker-compose.yaml содержит спецификацию для двух сервисов:

  1. timescale

    Это наша база данных Postgres с установленным расширением Timescale. Он настроен для работы на порту 5432.

  2. graphql-engine

    Это наш экземпляр Hasura GraphQL Engine, то есть сервер GraphQL, который указывает на базу данных и предоставляет API-интерфейсы GraphQL поверх нее. Он настроен для работы на порту 8080, а порт 8080 сопоставлен с портом 8080 машины, на которой работает этот док-контейнер. Это означает, что вы можете получить доступ к этому серверу GraphQL по адресу localhost:8080 машины.

Давайте запустим эти контейнеры докеров, выполнив следующую команду, где бы вы ни разместили свой docker-compose.yaml.

docker-compose up -d

Эта команда извлекает образы докеров из облака и запускает их в заданном порядке. Это может занять несколько секунд в зависимости от скорости вашего интернета. После завершения вы можете получить доступ к консоли GraphQL Engine по адресу https://localhost:8080/console.

Консоль Hasura GraphQL Engine

Консоль Hasura GraphQL Engine (большой предварительный просмотр)

Настройка базы данных

Далее давайте создадим таблицу с именем температура, в которой хранятся значения температуры в разное время. Перейдите на вкладку Данные в консоли и перейдите в SQL раздел. Создайте наш temperature таблицу, запустив этот блок SQL:

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

Это создает простую таблицу Postgres в базе данных. Но мы хотим использовать разделение временных интервалов расширения Timescale. Для этого мы должны преобразовать эту таблицу в гипертаблицу шкалы времени, выполнив команду SQL:

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

Эта команда создает гипертаблицу, разделенную по времени в поле recorded_at.

Теперь, когда эта таблица создана, мы можем напрямую приступить к выполнению запросов GraphQL к ней. Вы можете попробовать их, нажав на GraphiQL вкладка сверху. Сначала попробуйте сделать мутацию:

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

Приведенная выше мутация GraphQL вставляет строку в temperature Таблица. Теперь попробуйте сделать запрос GraphQL, чтобы проверить, были ли вставлены данные.

Затем попробуйте сделать запрос:

query {
  temperature {
    recorded_at
    temperature
    location
  }
}

Надеюсь, это сработало 🙂

Теперь наша задача состоит в том, чтобы создать диаграмму временных рядов в реальном времени, которая показывает максимальную температуру местоположения с интервалом в 5 секунд за последние 20 минут с настоящего момента. Давайте создадим представление, которое дает нам именно эти данные.

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
);

В этом представлении группируются данные из temperature таблица в 5-секундных окнах с их максимальной температурой (max_temp). Вторичная группировка выполняется с помощью location поле. Все эти данные только за последние двадцать минут с настоящего момента.

Вот и все. Наш бэкэнд настроен. Давайте теперь построим хороший график в реальном времени.

Внешний интерфейс

Привет подписки на GraphQL

Подписки GraphQL — это, по сути, «живые» запросы GraphQL. Они работают через WebSockets и имеют точно такую ​​же структуру ответов, что и запросы GraphQL. Возвращаться https://localhost:8080/console и попробуйте сделать подписку GraphQL на созданное нами представление.

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

Эта подписка подписывается на данные в представлении, где находится местоположение. London и упорядочены в порядке возрастания five_second_intervals.

Естественно, ответом представления будет пустой массив, поскольку за последние двадцать минут мы ничего не вставляли в базу данных. (Вы могли бы увидеть запись, которую мы вставили когда-то назад, если бы вы добрались до этого раздела в течение двадцати минут.)

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

Не снимая эту подписку, откройте другую вкладку и попробуйте вставить другое значение в temperatures table, используя ту же мутацию, которую мы выполнили ранее. После вставки, если вы вернетесь на вкладку, на которой была включена подписка, вы увидите, что ответ обновился автоматически. Это магия реального времени, которую обеспечивает GraphQL Engine. Давайте воспользуемся этой подпиской, чтобы включить нашу диаграмму в реальном времени.

Начало работы с приложением Create-React

Давайте быстро начнем работу со стартером приложения React, используя приложение create response. Запустите команду:

npx create-react-app time-series-chart

Это создаст пустой стартовый проект. cd в него и установите библиотеки GraphQL и диаграмм. Также установите момент для преобразования временных меток в удобочитаемый формат.

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

Наконец, запустите приложение с помощью npm start и базовое приложение React откроется в https://localhost:3000.

Необработанное приложение «создать-реагировать»

Raw creat-react-app (большой предварительный просмотр)

Настройка клиента Apollo для GraphQL на стороне клиента

Клиент Apollo в настоящее время является лучшим клиентом GraphQL, который работает с любым сервером, совместимым с GraphQL. Relay Modern тоже хорош, но сервер должен поддерживать спецификацию Relay, чтобы использовать все преимущества Relay modern. В этом руководстве мы будем использовать клиент Apollo для GraphQL на стороне клиента. Давайте выполним настройку, чтобы предоставить приложению клиент Apollo.

Я не буду вдаваться в тонкости этой настройки, потому что следующие фрагменты кода взяты непосредственно из документации. Направляйтесь к src/index.js в каталоге приложения React и создайте экземпляр клиента Apollo и добавьте этот фрагмент кода выше 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
});

Наконец, оберните App внутри ApolloProvider чтобы мы могли использовать клиент Apollo в дочерних компонентах. Ваш App.js должно наконец выглядеть так:

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')
);

Клиент Apollo настроен. Теперь мы можем легко использовать GraphQL в реальном времени из нашего приложения. Направляйтесь к src/App.js.

Построение диаграммы

ChartJS предоставляет довольно удобный API для построения диаграмм. Мы будем строить линейный график; поэтому линейная диаграмма ожидает данные в форме:

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

Если приведенный выше набор данных используется для рендеринга линейной диаграммы, он будет выглядеть примерно так:

Образец линейной диаграммы

Образец линейного графика (большой предварительный просмотр)

Давайте сначала попробуем построить этот образец диаграммы. Импортировать Line от react-chartjs-2 и визуализировать его, передавая указанный выше объект в качестве реквизита данных. Метод рендеринга будет выглядеть примерно так:

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>
  );
}

Далее мы подпишемся на данные в нашем представлении и передадим их на линейный график. Но как мы выполняем подписки на клиенте?

Аполлона <Subscription> компоненты работают с использованием шаблона поддержки рендеринга, где дочерние элементы компонента визуализируются в контексте данных подписки.

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

Воспользуемся одним из таких Subscription компонент, чтобы подписаться на наше представление, а затем преобразовать данные подписки в структуру, которую ожидает ChartJS. Логика трансформации выглядит так:

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');
})

Примечание: Вы также можете использовать библиотеку с открытым исходным кодом graphq2chartjs для преобразования данных из ответа GraphQL в форму, ожидаемую ChartJS.

После использования этого внутри компонента Subscription наш App.js похоже:

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;

У вас будет полностью рабочий график в реальном времени, готовый к https://localhost:3000 . Однако он будет пустым, поэтому давайте заполним некоторые образцы данных, чтобы мы действительно могли увидеть, как происходит какое-то волшебство.

Примечание: Я добавил еще несколько параметров в линейный график, потому что мне не нравятся эти причудливые анимации в ChartJS. Временной ряд выглядит мило, когда он прост, однако вы можете удалить поддержку параметров, если хотите.

Вставка демонстрационных данных

Давайте напишем скрипт, который заполняет нашу базу данных фиктивными данными. Создайте отдельный каталог (вне этого приложения) и создайте файл с именем script.js со следующим содержанием,

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
);

Теперь запустите эти две команды:

npm install --save node-fetch
node script.js

Вы можете вернуться к https://localhost:3000 и увидеть обновление графика.

Заканчивать

Вы можете построить большинство графиков в реальном времени, используя идеи, которые мы обсуждали выше. Алгоритм:

  1. Развернуть GraphQL Engine с Postgres;
  2. Создайте таблицы, в которых вы хотите хранить данные;
  3. Подпишитесь на эти таблицы из своего приложения React;
  4. Отобразите диаграмму.

Вы можете найти исходный код здесь.

Сокрушительная редакция
(дм, ра, ил)




Source: https://smashingmagazine.com

Заключение

Вы ознакомились с статьей — Построение диаграмм в реальном времени с помощью GraphQL и Postgres

Пожалуйста оцените статью, и напишите комментарий.

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован.

Кнопка «Наверх»