Новый способ создания динамических визуализаций

1656640347 novyj sposob sozdaniya dinamicheskih vizualizaczij

Сушрут Шивасвами

1*pXitH0oMDdrvQRHjFsNM5g

Архитектура Flux приобрела популярность после того, как Facebook принял ее. Это способ управления состоянием компонентов React, чтобы поток данных через приложение был однонаправленным.

Преимущества этого подхода заключаются в том, что программа состоит из нескольких компонентов с сохранением состояния, которые передают состояние во вложенные дочерние компоненты. Особенностью React, действительно дополняющей этот подход к управлению состоянием, является то, что React позволяет нам писать UI как функцию состояния. Это означает, что, когда состояние просачивается вниз по иерархии компонентов программы, компоненты автоматически изменяют вид, чтобы отобразить изменения в состоянии.

JSX, система шаблонов, используемая React, позволяет создавать многократно используемые однофайловые компоненты.

Он также очень хорошо подходит для создания разграничения между структурой DOM и связанным с ней поведением.

  • JSX дает четкое представление о структуре DOM, которое более интуитивно понятно, чем несколько строк JavaScript, необходимых для создания той же структуры DOM.
  • Поведение, связанное со структурой DOM – обработчики событий, такие как onClick, onHover – обрабатываются как функции-члены компонента.
  • Любые изменения в структуре DOM требуют пользовательского вызова setState, чтобы изменить состояние компонента вместо непосредственного изменения DOM. Это облегчает настройку программы, а также гарантирует, что программа всегда находится в определенном состоянии.

Однако с ростом сложности программы подход Flux тоже начал демонстрировать свои ограничения.

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

Хотя можно поделиться состоянием между разными компонентами/классами в JavaScript с помощью общих переменных или, желательно, шаблона наблюдателя, с увеличением количества компонентов становится труднее поддерживать приложение.

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

Диаграммы – почему их трудно создать?

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

Однако диаграммы отличаются в одном ключевом аспекте: разработчики не считают SVG DOM. Технически, <sТег vg> даже не HTMLElement, как другие элементы DOM, и находится в отдельном пространстве имен. SVG известен своей способностью масштабировать до любого размера окна просмотра и поддерживать разрешение изображения на постоянном уровне. Это то, как большинство разработчиков знают об этом.

Также теги, которые используются для создания изображения SVG, например <point>, &lt;прямой />, and звук <ламана /> очень «похож на математику». Это заставляет разработчиков избегать того, как на самом деле работают структуры SVG.

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

Избежав основной сложности SVG, можно легко моделировать сложные конструкции SVG.

Геометрия

Рассмотрим, например, столбчатую диаграмму.

0*TODhoVI3-CTxOhWU
Хорошая гистограмма.

Мы традиционно используем подход формочки для печенья и делим диаграмму на две части:

Опытный разработчик заметил бы, что слово axis было написано дважды в вышеприведенном списке. Итак, давайте создадим уровень абстракции под названием Axis какие подклассы могут наследовать.

Чтобы показать полосы, мы можем создать отдельный класс под названием Bar что использует масштаб, предоставленный axis класс. Поскольку диаграммы имеют разные формы, целесообразнее иметь уровень абстракции под названием Geometry которые могут наследовать другие классы, а именно Bar, Point, Lineи Area. По мере сотворения более сложных диаграмм можно добавить несколько новейших типов геометрии для визуализации разных типов диаграмм.

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

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

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

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

Наличие перекрестной связи между диаграммами еще больше усугубляет эту проблему. Оркестровка изменений состояния включает несколько диаграмм/взаимодействующих компонентов.

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

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

Примечание: В следующем разделе объясняется, как использование Redux облегчает разработку веб-приложений. Не стесняйтесь упустить это, если вы уже знаете о Redux.

Redux

Redux – это библиотека, разработанная Дэном Абхрамовым. Это помогает облегчить бремя разработчиков, предоставляя простой способ поддерживать состояние программы.

Redux представил концепцию хранилища состояния, выступающего единственным источником правды для всей программы. Вместо того чтобы компоненты непосредственно изменяли состояние, каждый компонент отправлял бы действие, которое вносило бы изменения в единое хранилище состояния.

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

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

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

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

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

Успех модели React-Redux породил ряд других библиотек, таких как Vue и Cycle, а также несколько других реализаций хранилища состояния, таких как MobX и Vuex.

Детальнее о SVG

SVG означает масштабируемую векторную графику. The svg Тег может опционально содержать разные типы геометрии, отображающие ряд атрибутов DOM.

Круг: <circle />

Атрибуты:

  • cx: x смещение круга в окне просмотра
  • cy: y смещение круга в окне просмотра
  • р : радиус круга.

Ломаная линия: <polyline />

Атрибуты:

  • баллы: массив точек (x, y), через которые a линия нарисован.

Многоугольник: <polygon />

Атрибуты:

  • точки: массив точек (x, y) для построения многоугольника.

текст: <text />

Атрибуты:

  • x: x смещение текста в окне просмотра
  • y: y смещение текста в окне просмотра
  • внутренний текст: текст для показа.

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

Найти мост

Это руководящие принципы разработки современных веб-приложений и разработки библиотек диаграмм. Давайте попробуем определить, чем разработка библиотек диаграмм отличается от веб-приложений:

  • веб-приложения состоят из узлов DOM. Диаграммы состоят из геометрии SVG.
  • веб-приложения можно разбить на повторно используемые разделы DOM, которые можно моделировать как компоненты. Диаграммы не моделируются как многократный набор геометрий.
  • веб-приложение фреймворки всегда совмещаются с механизмом создания шаблонов, чтобы структуру DOM можно было смоделировать в разметке, а поведение можно отделить от него и записать на JavaScript. Диаграммы нет такой основы.
  • веб-приложение Фреймворки позволяют интегрировать хранилище состояния с помощью плагина. Диаграммы обычно моделируются как компоненты состояния.

Ремоделирование диаграммы сложности

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

Итак, как это работает?

0*sIbDX48h24oTItLL
Хорошая диаграмма разброса

Глядя на график выше, что мы видим? Смещение кругов в окне просмотра на основе полей данных.

Что еще?

  • Смещение галочек вдоль нижней части на основе поля данных.
  • Текстовые метки смещены вдоль низа на основе поля данных.
  • То же, что и выше, в левой части диаграммы.

Давайте разберем это до уровня геометрии.

Как мы визуализируем круги на диаграмме рассеяния?

<circle cx=”horsepowerScale()” cy=”milesPerGallonScale()” cr=”const” />

Что с топорами? Оси X: текст + галочки

<text x=”horsepowerScale()” y=”0”>{{ text value }}&lt;/текст>

<tick x=”horsepwerScale()” y=”0” />

Существует подобная структура SVG для оси y, за исключением того, что функция масштабирования изменяется, а поля x, y инвертируются.

Общей темой выше является то, что диаграмма рассматривается как значимое расположение геометрии:

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

Что такое шкала?

Масштаб – это функция, отображающая данные в позиции в окне просмотра.

Что такое входные данные для зума?

  • домен поля
  • длина окна просмотра для отображения

Позволяет Р быть длиной окна просмотра и д быть доменом данных.

  • Тогда мы можем определить функцию масштабирования С как:
  • S = f(D, R) + b

где b является константой.

Сколько масштабов должна иметь диаграмма?

Если вы думаете о двух, то вы ошибаетесь.

Масштаб существует не только вдоль осей x и y. Сами оси присутствуют только на диаграмме как визуальные привязки так что пользователи могут строить вариации данных по нескольким измерениям.

Ось это просто геометрия, которая отображается с помощью масштаба.

Сколько там измерений?

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

Общая концепция состоит из двух простых терминов: Геометрия и масштаб.

Каждая геометрия демонстрирует визуальные атрибуты, контролирующие ее облик.

Значения этих атрибутов можно подключить к функциям зума. Функция зума привязана к определенному полю в данных.

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

Учитывая эту декомпозицию диаграмм, мы можем смоделировать приведенную выше диаграмму рассеяния следующим образом:

Поле Horsepower используется для создания функции зума под названием horsepowerScale().

Поле Acceleration используется для создания функции зума под названием accelerationScale().

Поскольку мы не изменяем размер кругов, требуются только две функции масштабирования.

Любой круг i на диаграмме рассеяния можно представить как

<circle cx="horsepowerScale(ti)" cy="accelerationScale(ti)" cr="5" />

где ti есть iи кортеж в Datatable.

Учитывая, что были использованы только две функции масштабирования, размерность приведенной диаграммы становится двумя.

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

Это приведет к так называемой «пузырчатой ​​диаграмме».

Грамматика графики

Это сродни подходу грамматики графики (GOG), где каждая диаграмма определяется пометкой (геометрией) и визуальным кодированием, которое использует отметка.

В подходе GOG диаграмма рассеяния будет представлена ​​как:

{
    mark: 'circle',
    encoding: {
        x: 'horsepower',
        y: 'acceleration'
    }
}

Обратите внимание, что существует однозначное отображение между кодировкой геометрии GOG и визуальными атрибутами, открываемыми геометрией в SVG..

Вот также можно отобразить подобным образом:

  • Ось х – это тик-геометрия с привязанным атрибутом смещения по оси x horsepowerScale() и его y-смещение установлено на 0.
  • Ось y – это тик-геометрия с привязанным к ней атрибутом y-offset accelerationScale() а его x-смещение установлено на 0.

Для отображения точечной диаграммы со всеми ее элементами будет достаточно следующего фрагмента кода:

Декомпозиция диаграмм на ассоциацию между визуальными атрибутами и функцией зума позволяет нам просматривать диаграмму как веб-приложение.

Фреймворки веб-приложений моделируют UI как функцию состояния.

Платформы диаграмм должны моделировать геометрию как функцию масштаба.

Поэтому идею, облегчающую разработку веб-приложений, можно легко распространить на создание диаграмм:

  • Первоначально табличные данные представляются как входные данные.
  • Для каждого поля в массиве данных создается функция зума. Функция зума выборочно повторно вычисляет значение, когда поле в столбце привязано к изменениям. Такая же функция зума распространяется на всю программу.
  • Каждая геометрия моделируется как компонент, раскрывающий визуальные атрибуты.
  • Значение этих визуальных атрибутов связано с функцией зума, которая реагирует на изменения в данных.
  • Коллекции геометрии могут быть представлены в разметке с помощью выбранного механизма создания шаблонов, например гиперHTML, усов или руля. В идеале механизм создания шаблонов должен быть представлен как плагин, чтобы мы могли избежать написания привязок для разных библиотек, таких как React и Angular.
  • Хранилище состояний, избирательно вычисляющее масштабы, также должно быть представлено как плагин.

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

В приведенном выше примере мы используем React как механизм создания шаблонов и Redux как хранилище состояния.

Приведенный выше подход является лишь приблизительной реализацией того, что хотел бы фреймворк, который может моделировать диаграммы как веб-приложения.

Обратите внимание на разделение механизма создания шаблонов и хранилища состояния от фактической логики воспроизведения.

Заключительные пункты

В идеале геометрии/диаграммы, которые мы создаем, должны быть доступны как компоненты в рамках выбора пользователя вместе с хранилищем состояния. Если кажется невероятным, что нечто подобное вообще можно сделать, сохраняйте спокойствие. Это было сделано раньше.

SkateJS – это компилятор, создающий веб-компоненты, но позволяющий пользователю переключать внутренние механизмы визуализации.

Пользователи могут выбирать между React, Preact, lit-html или расширить интерфейс Renderer, чтобы написать свой собственный. Средство рендеринга по умолчанию просто изменяет DOM напрямую.

Мы можем быть еще более амбициозными относительно того, что мы выбираем, если у нас будет синхронная визуализация в сочетании с управлением состоянием.

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

Учитывая, что диаграмма является значимым упорядочением геометрии, следует, что значимые кластеры геометрии должны отображаться вместе.

В примере диаграммы рассеяния для каждой группы визуализируемых кругов соответствующие участки геометрии оси x/y также должны воспроизводиться одновременно.

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

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

Мы можем также разбить расчет значений визуальных атрибутов.

Рассмотрим таблицу данных, которая имеет Н поля, используемые для визуализации информационных панелей с помощью вышеописанного подхода.

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

Также рассмотрим уравнение ниже, которое вычисляет значение м визуальные атрибуты на основе функций зума.

Нулевое значение для визуального атрибута Вкоторый привязан к полю 0 с Нможно рассчитать следующим образом:

V(0) = S(d0, R) + b0

  • где d0 – 0-й кортеж данных из таблицы данных
  • R — это диапазон, предоставляемый как проп для компонента
  • b0 постоянная

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

V(0) = S(d0, R) + b0

V(1) = S(d1, R) + b1

V(2) = S(d2, R) + b2

..

V(m) = S(dm, R) + bm

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

Как это?

Вышеприведенное расположение выглядит подозрительно как матрица.

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

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

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

Можно с уверенностью сказать, что нам нужен более надежный, доступный и удобный способ разработки визуализаций.

Как ты думаешь?

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

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