Практика применения большого экрана React Data

визуализация данных
Практика применения большого экрана React Data

Эта статья была впервые опубликована вблог hzzly

Оригинальная ссылка:Практика применения большого экрана React Data

Большой экран данных и визуализация данных

В настоящее время большие данные распространены повсеместно и все шире применяются в истории, политике, науке, экономике, бизнесе и даже проникают во все аспекты нашей жизни, а каналы доступа становятся все более и более удобными.

Сегодня давайте поговорим о «приложениях для большого экрана». Когда речь идет о больших экранах, мы должны говорить о визуализации данных. В настоящее время визуализация данных стала популярной из-за популярности анализа данных, но визуализация данных не является новой технологией. данные — это данные, представленные в визуальном виде. Как своего рода средство отображения больших данных, экран больших данных широко используется в различных выставочных залах, выставках, пресс-конференциях и различных карнавалах, среди которых есть некоторые общие решения для обработки: DataV от Ali, Suger от Baidu, RayData от Tencent и т. д.

С появлением и развитием различных технологий, связанных с подключением, таких как Интернет вещей и 5G, количество данных, находящихся в руках каждого, выросло в геометрической прогрессии. Невозможно прочитать или понять, просто взглянув на эти цифры». Визуализация данных " - это упрощение, которое превращает сложный процесс понимания данных в рассмотрение цветов, различение длин и шорт, а также различение высокого и низкого. Это значительно сокращает время, необходимое для понимания данных.

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

Ниже приведены некоторые из методов исследования, которые я использую для этих данных, требующих большого экрана, данные также являются МОДЕЛИРУЕМЫМИ.

gif图

Выбор технологии

  • Ведро семейства React (React-Router, React-Redux, React Hooks)
  • Компиляция и упаковка Webpack
  • Компоненты диаграмм
  • Обмен мгновенными сообщениями Socket.IO, уведомление и отправка сообщений
  • Компоновка сетки сетки

Строительство системы

Выбор диаграммы

Шесть основных диаграмм охватывают большинство сценариев использования диаграмм и являются наиболее часто используемыми типами диаграмм для визуализации данных:

  • ГистограммаИспользуется для отражения сравнения между категориальными элементами;
  • Круговая диаграммаОн используется для отражения композиции, то есть пропорции части к целому;
  • линейный графикиспользуется для отражения тенденций с течением времени;
  • гистограммаИспользуется для отражения сравнения между категориальными элементами;
  • График рассеянияИспользуется для отражения корреляции или отношения распределения;
  • картаИспользуется для отражения классификационных сравнений между регионами.

Основные типы диаграмм имеют общие стили, но объяснять их будет слишком много. Мы больше думаем о том, как выбрать общие диаграммы для представления данных и достижения цели визуализации данных. основной метод:ясная цель—>выбрать графику—>гребенчатые размеры—>Выделите ключевую информацию.

Push-запрос данных

Как только информация будет готова, нам нужно получить ее с сервера. Здесь нам нужен подход на основе push-уведомлений, такой как протокол WebSocket, опросы, события Server Push Events (SSE) и совсем недавно HTTP2 Server Push. Здесь мы кратко сравним WebSocket и опрос.

Опрос требует, чтобы клиент периодически отправлял запрос Ajax на сервер, и сервер возвращал ответ после получения запроса. Это требует много ресурсов сервера. В то же время в протоколе HTTP1.x также есть некоторые проблемы, такие как блокировка заголовков строк и избыточность заголовков. Так что эта схема передается напрямую.

Давайте поговорим о WebSocket, построенном на протоколе TCP, формат данных относительно легкий, потери производительности невелики, связь эффективна, и он может отправлять текстовые или двоичные данные. В то же время у него нет ограничений на одно и то же происхождение, и клиент может общаться с любым сервером. Еще один момент заключается в том, что WebSocket обычно не использует XMLHttpRequest, поэтому каждый раз, когда нам нужно получить больше информации от сервера, нам не нужно отправлять данные заголовка. Это, в свою очередь, снижает штраф за высокую загрузку данных при отправке данных на сервер. Это, несомненно, наиболее эффективно для больших экранов данных, которым необходимо получать данные в режиме реального времени.

макет

Ядром экрана больших данных является сращивание данных, в частности, уровень отображения может быть сведен к сращиванию блоков данных. Здесь мы используем общий размер 1920*108 (16:9). После того, как размер установлен, следующим шагом будет размещение слоя отображения и разделение страницы. Разделение здесь в основном основано на бизнес-показателях, которые мы установили ранее, основные бизнес-показатели расположены посередине и занимают большую площадь, остальные показатели развернуты вокруг основных показателей в порядке приоритета. Как правило, связанные индикаторы размещаются рядом или близко друг к другу, а индикаторы с аналогичными типами диаграмм размещаются вместе, что может снизить когнитивную нагрузку на зрителя и повысить эффективность передачи информации.

Для этого блочного (сеточного) макета мы можем использовать нашу мощную схему макета CSS —Grid. Он делит веб-страницы на сетки, и вы можете произвольно комбинировать разные сетки для создания различных макетов.

Amway — инструмент визуального дизайна с сеткой —CSS Grid Generator. Вы можете использовать его для создания соответствующего кода, который поможет нам быстро выполнить макет.

grid

Структура проекта

Поговорив об этих общих знаниях, мы можем приступить к разработке.

Я использовал собственные разработанные леса (hzzly-cli) для создания среды реактивного проекта.

Если вам интересно узнать о разработке скаффолдинга, вы можете прочитать мою статьюРазработайте свой собственный проект строительных лесов

Структура проекта следующая:

├── src
│   ├── assets // 资源目录
│   ├── components // 公共组件目录
│   │   ├── Card // Card组件
│   │   ├── Charts // 图表组件目录
│   │   │   ├── Bar // 柱状图
│   │   │   ├── ChinaMap // 中国地图
│   │   │   ├── Funnel // 漏斗图
│   │   │   ├── Line // 折线图
│   │   │   ├── Pie // 饼图
│   │   │   └── lib // 基础图表组件
│   │   ├── ScrollNumber // 滚动数字组件
│   │   └── SvgIcon // Icon组件
│   ├── global.scss
│   ├── index.js
│   ├── pages // 分块结构目录
│   ├── router // 路由
│   ├── store
│   │   ├── actions
│   │   ├── index.js
│   │   ├── reducers
│   │   ├── sagas
│   │   └── types.js
│   └── utils
│       ├── genChartData.js
│       ├── genMapData.js
│       ├── socket.js
│       └── util.js

Точка знаний

Базовый пакет компонентов Chart

Прямо здесьecharts-for-reactДальнейшая инкапсуляция позволяет напрямую наследовать и использовать другие компоненты диаграммы.

// Charts/lib/BaseChart.js
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import Echarts from 'echarts-for-react';

export default class BaseChart extends PureComponent {
  static propTypes = {
    option: PropTypes.object.isRequired,
    data: PropTypes.object.isRequired,
    getOption: PropTypes.func.isRequired,
    style: PropTypes.object,
  };

  static defaultProps = {
    style: {},
  };

  componentDidMount() {
    const { runAction } = this.props;

    if (this.chartRef && runAction) {
      const chartIns = this.chartRef.getEchartsInstance();
      window.setTimeout(() => {
        runAction(chartIns);
      }, 300);
    }
  }

  render() {
    const { option, data, getOption, style } = this.props;

    const finalOption = getOption(option, data);
    const finalStyle = getStyle(style);

    return (
      <Echarts
        ref={ref => {
          this.chartRef = ref;
        }}
        style={finalStyle}
        option={finalOption}
        notMerge
        lazyUpdate
      />
    );
  }
}

function getStyle(style) {
  return Object.assign({ position: 'relative' },
    style
  );
}

использовать:

// line.js
import BaseChart from '../lib/BaseChart';
import option from './option';
import getOption from './getOption';

export default class Line extends BaseChart {
  static defaultProps = {
    option,
    getOption,
  };
}

// option.js 基础配置
export default {
  // ...
};

// getOption.js 计算配置文件
function seriesCreator(series) {
  return series.map(e => ({
    type: 'line',
    symbol: 'circle',
    smooth: true,
    lineStyle: {
      normal: {
        width: 3,
      },
    },
    ...e,
  }));
}

export default function(option, data) {
  const { tooltip, xAxis, yAxis, yCategory, series = [], ...rest } = data;

  return {
    ...option,
    xAxis: {
      ...option.xAxis,
      ...xAxis,
    },
    tooltip: {
      ...option.tooltip,
      ...tooltip,
    },
    yAxis: {
      ...option.yAxis,
      ...yAxis,
      data: yCategory || [],
    },
    series: seriesCreator(series),
    ...rest,
  };
}

SDK пакета сокетов

Прямо здесьsocket.io-clientУпакован в SDK, прост в использовании.

import io from 'socket.io-client';

const socket = {
  wsConn: null,
  config: {
    wsHost: '/', // wesocket host

    onConn() {},
    onDisconn() {},
    onError() {},
    onReceiveMsg() {},
  },

  init(opt) {
    socket.config = { ...socket.config, ...opt };
  },

  getWs() {
    if (socket.wsConn) {
      return socket.wsConn;
    } else {
      socket.initWs();
    }
  },

  getWsStatus() {
    return socket.wsConn ? socket.wsConn.connected : false;
  },

  initWs() {
    if (socket.getWsStatus()) {
      return socket.wsConn;
    }

    const wsUrl = socket.config.wsHost;

    socket.wsConn = io.connect(wsUrl);
    socket.wsConn.on('connect', () => {
      socket.config.onConn(socket.wsConn);
    });

    socket.wsConn.on('message', (...param) => {
      socket.config.onReceiveMsg(...param);
    });

    socket.wsConn.on('disconnect', () => {
      socket.config.onDisconn();
    });
    return socket.wsConn;
  },

  reconnect() {
    if (socket.wsConn) {
      if (socket.wsConn.disconnected) {
        // reconnect ws
      } else {
        // do nothing
      }
    } else {
      socket.initWs();
    }
  },

  disconnect() {
    if (socket.wsConn) {
      if (socket.wsConn.connected) {
        socket.wsConn.disconnect();
      }
    }
  },

  wsEmit(params) {
    if (socket.wsConn) {
      socket.wsConn.emit(params.name, params.data);
    }
  },
};

(function(global) {
  global.socket = socket;
})(window);

export { socket };

Динамический цифровой дисплей

Данные обновляются в режиме реального времени через сокет push.

Динамический эффект цифрового перехода заключается в том, что новый номер соответствующей цифры заменяет старый номер снизу вверх.Если номер цифры не изменился, эффекта перехода нет.

1、对数据进行完善并格式化

Заполнение начальными нулями и форматирование тысячных для чисел, содержащих менее 9 цифр.

const MAX_LEN = 9;

function toThousands(val) {
  let num = (val || 0).toString();
  while (num.length < MAX_LEN) {
    num = `0${num}`;
  }
  let result = '';
  while (num.length > 3) {
    result = `,${num.slice(-3)}${result}`;
    num = num.slice(0, num.length - 3);
  }
  if (num) {
    result = num + result;
  }
  return result.toString().split('');
}

2、过渡动画

Используйте стили для управления анимацией перехода, на первом этапе мы форматируем числа, затем сравниваем каждую цифру и добавляем, когда числа не равныactiveкласс, наконецactiveКласс для добавления анимации.

// 循环渲染每一位数字
<li className={`${oldNumber[i] !== newNumber[i] ? 'active' : ''}`}>
  <span className="num">{oldNumber[i]}</span>
  <span className="num">{newNumber[i]}</span>
</li>
.active {
  .num {
    animation: move 1.5s;
    animation-fill-mode: forwards; // 让动画结束后保持最后一帧
  }
}

@keyframes move {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-100%);
  }
}

фоновые линейные частицы

Здесь я использую свои собственные упакованные компоненты, которые можно установить и ссылаться на них в соответствии с фреймворком:

иллюстрировать

1. Структура каталогов Project Projode использует собственную среду автора WebPack:webpack-template

2. Адаптация и совместимость еще не доведены до совершенства, если будет время на более позднем этапе, будем постепенно улучшать.

3. Этот проект является практикой автора во время исследования.Из-за ограниченного времени и некоторых функций, дизайн и макет являются моим собственным воображением и ссылкой.

4. Этот проект используется для обучения с открытым исходным кодом и не может использоваться для коммерческих приложений.

Ссылаться на