Создание интерактивной инфографики с помощью Vue.js
Опубликовано: 2022-03-10В данной статье представлен современный подход к построению интерактивной инфографики. Вы наверняка можете иметь простую инфографику со всей доступной информацией заранее — без какого-либо взаимодействия с пользователем. Но мысли о создании интерактивного опыта меняют выбранный нами технологический ландшафт. Поэтому давайте сначала разберемся, почему именно Vue.js? И вы увидите, почему GSAP (платформа анимации GreenSock) и SVG (масштабируемая векторная графика) становятся очевидным выбором.
Vue.js предоставляет практические способы создания динамических пользовательских интерфейсов на основе компонентов, где вы можете эффективно манипулировать элементами DOM и управлять ими. В данном случае это будет SVG. Вы можете легко обновлять различные элементы SVG и управлять ими — динамически — используя лишь небольшое подмножество функций, доступных в Vue.js — некоторые из основных функций, которые отвечают всем требованиям, — это привязка данных, рендеринг списка, динамическая привязка немного. Это также позволяет группировать соответствующие элементы SVG вместе и разделять их на компоненты.
Vue.js хорошо работает с внешними библиотеками, не теряя при этом своей славы, то есть здесь GSAP. Есть много других преимуществ использования Vue.js, одно из которых заключается в том, что Vue.js позволяет изолировать связанные шаблоны, сценарии и стили для каждого компонента. Таким образом, Vue.js продвигает модульную структуру приложения.
Рекомендуемая литература : Замена jQuery на Vue.js: этап сборки не требуется
Vue.js также поставляется с мощными хуками жизненного цикла, которые позволяют вам подключаться к различным этапам приложения для изменения поведения приложения. Настройка и обслуживание приложений Vue.js не требуют больших усилий, а это означает, что вы можете использовать поэтапный подход для масштабирования своего проекта по мере продвижения.
Инфографика очень легкая в визуальном смысле, поскольку основная цель этой статьи — научиться думать с точки зрения данных, визуальных элементов и, конечно же, Vue.js — фреймворка, который делает возможным всю интерактивность. Кроме того, мы будем использовать GreenSock, библиотеку для анимации элементов SVG. Прежде чем мы углубимся, взгляните на демо.
Мы начнем с:
- Обзор данных для инфографики;
- подготовка SVG-изображения;
- Обзор компонентов Vue в контексте иллюстрации SVG;
- Примеры кода и диаграммы ключевой интерактивности.
Инфографика, которую мы собираемся создать, посвящена Tour De France, ежегодному соревнованию по велогонкам, проводимому во Франции.

Обзор данных Тур де Франс
В инфографическом дизайне данные определяют дизайн вашей инфографики. Поэтому при планировании инфографического дизайна всегда полезно иметь все данные, информацию и статистику по заданной теме.
Во время Тур де Франс 2017 года я узнал об этом крупнейшем велособытии все, что мог за 21 игровой день в июле, и ознакомился с предметом.
Основные сущности гонки, которые я решил использовать в своем дизайне, это:
- Этапы,
- Команды,
- Маршруты,
- Победители,
- Протяженность и классификация каждого маршрута.
Эта следующая часть процесса зависит от вашего стиля мышления, так что здесь вы можете проявить творческий подход.
Я создал два набора данных, один для этапов, а другой для команд. Эти два набора данных имеют несколько строк данных (но within limit
), которые соответствуют двум колесам велосипеда с несколькими спицами в каждом. И это определило ключевой элемент дизайна, The Bicycle Art
, который вы видели в начале, где каждая спица будет интерактивной и ответственной за управление той информацией, которая отображается на экране.
Я упомянул об within limits
выше, потому что в данном случае мы стремимся не к полноценной визуализации данных в контексте больших данных, а скорее к инфографике с данными высокого уровня.
Поэтому проводите время с данными и ищите сходства, различия, иерархию или тенденции, которые помогут вам передать визуальную историю. И не забывайте об удивительном сочетании SVG и Vue.js, поскольку это поможет вам найти правильный баланс между информацией (данными), интерактивностью (Vue.js) и элементами дизайна (SVG Artwork). ) инфографики.
Вот фрагмент объекта данных сцены:
{ "ID": 1, "NAME": "STAGE 01", "DISTANCE": "14", "ROUTE": "KMDUSSELDORF / DUSSELDORF", "WINNER": "THOMAS G.",
"UCI_CODE": "SKY",
"TYPE": "Individual Time Trial",
"DATE": "Saturday July 1st",
"KEY_MOMENT": " Geraint Thomas takes his first win at 32"
}
И фрагмент объекта данных команды, как показано ниже:
{ "ID": 1,
"UCI_CODE": "SKY",
"NAME": " TEAM SKY",
"COUNTRY": "Great Britain",
"STAGE_VICTORIES": 1,
"RIDERS": 8
}
Эта инфографика управляется очень простой логикой.
UCI_CODE (Международный союз велосипедистов) является связующим звеном между этапом и объектом команды. При нажатии на этап сначала мы активируем этот этап, но также используем ключ UCI_CODE
для активации соответствующей команды-победителя.
Подготовка SVG
Имея пару готовых наборов данных и приблизительную концепцию велосипедного искусства, вот статичный SVG CodePen инфографики, которую я придумал.
См. SVG Pen Static Bicycle от Krutie(@krutie) на CodePen.
Мы создали только одну спицу для каждого колеса, потому что мы будем динамически создавать остальные спицы, используя ряд записей, найденных в наборе данных, и анимировать их с помощью библиотеки GreenSock.
Рабочий процесс для создания этого кода SVG также очень прост. Создайте свою инфографику в Adobe Illustrator и сохраните в формате SVG. Не забудьте назвать каждую group
и layer
при работе в Illustrator, потому что вам понадобятся эти идентификаторы для разделения частей кода SVG, которые в конечном итоге заполнят область <template>
компонентов Vue. Помните, что имена слоев, заданные в Illustrator, становятся element ids
в разметке SVG.
Вы также можете использовать SVGOMG и дополнительно оптимизировать код SVG, экспортированный из Adobe Illustrator.
Важное примечание. Если вы используете SVGOMG для оптимизации разметки SVG, ваш код, безусловно, будет выглядеть аккуратно, но учтите, что он преобразует все элементы <rect> в <path> с атрибутом d
. Это приводит к потере значений x
и y
прямоугольника на тот случай, если позже вы захотите отрегулировать несколько пикселей вручную.
Во-вторых, обязательно снимите флажок « Clean Id
» (параметры справа в интерфейсе SVGOMG), это поможет сохранить все группы и идентификаторы, созданные в Illustrator, нетронутыми.
Обзор компонента Vue
Даже если интерактивность и поток данных в вашем инфографическом проекте довольно просты по своей природе, вы всегда должны уделить время составлению древовидной диаграммы компонентов.
Это особенно поможет, если вы не используете какой-либо механизм общих данных, где дочерние компоненты зависят от значений, отправленных родительским компонентом (т. е. через реквизиты) или наоборот (т. е. события this.$emit). Это ваш шанс провести мозговой штурм этих значений свойств, создать события и локальные данные — и задокументировать их, прежде чем приступить к написанию кода.

Диаграмма выше — это снимок компонентов Vue, который частично основан на требованиях к интерактивности и частично на основе разметки SVG. Вы должны увидеть, как разметка SVG будет разделена на основе этой древовидной структуры. Это довольно очевидно с точки зрения иерархии.
- Звездочка будет имитировать вращение спиц.
- Компонент сцены — это заднее колесо, на котором будут перечислены все 21 этап.
- Компонент Stage-detail будет отображать соответствующую информацию на изогнутом пути (слева).
- Командный компонент — это переднее колесо, на котором будут перечислены все участвующие команды на спицах.
- Компонент Team-detail будет отображать связанную информацию по изогнутой траектории (справа).
- Навигация будет включать кнопки «Назад» и «Далее» для доступа к этапам.
На приведенной ниже диаграмме представлены те же компоненты Vue, что и выше, но в контексте инфографического дизайна.

Чем меньше, тем лучше — такой подход следует использовать при работе над похожими проектами. Продумайте свои требования к анимации и переходу, если вы можете обойтись без использования TweenLite вместо TweenMax — сделайте это. Если у вас есть возможность выбрать элементарные формы и более простые пути вместо сложных — во что бы то ни стало попробуйте выбрать легкие элементы, которые легко анимировать — без каких-либо потерь производительности.
В следующем разделе вы познакомитесь с захватывающей частью анимации GreenSock и Vue.js.
ГринСок Анимация
Давайте подробнее рассмотрим:
- Текстовая анимация по изогнутой траектории;
- Спицевая анимация на руле.
Помните кривую траекторию, видимую вокруг велосипедного колеса, эта кривая траектория немного больше, чем радиус велосипедного колеса. Поэтому, когда мы анимируем текст на этом пути, он будет выглядеть так, как будто он повторяет форму колеса.

См. Текст пера на изогнутом пути от Krutie (@krutie) на CodePen.
path
и textPath
— это удачное сочетание элементов SVG, позволяющее размещать текст на любом пути с помощью xlink:href
.
<pathlanguage-javascript">curvedPath
" stroke="none" fill="none" d="..."/>
<text>
<textPath xlink:href="
#curvedPath
"
class="stageDetail"
startOffset="0%">
{{ stage.KEY_MOMENT }}
</textPath>
</text>
Чтобы анимировать текст вдоль пути, мы просто анимируем его атрибут startOffset
с помощью GreenSock.
tl.fromTo( ".stageDetail", 1, { opacity: 0,
attr: { startOffset: "0%" }
},
{
opacity: 1,
attr: { startOffset: "10%" }
}, 0.5 );
По мере увеличения процента startOffset
текст будет перемещаться дальше по периметру круга.
В нашем финальном проекте эта анимация запускается каждый раз при нажатии любой спицы. Теперь давайте перейдем к более захватывающей части анимации.
Анимация стадий/спиц внутри колеса
Из демо видно, что компоненты stage
и team
схожи по своей природе с парой небольших отличий. Итак, давайте сосредоточимся только на одном колесе велосипеда.
В приведенном ниже примере CodePen показаны только три ключевые идеи:
- Получить данные этапа;
- Упорядочивать спицы динамически на основе данных;
- Переупорядочите спицы при нажатии на сцену (спицы).
См. анимацию колеса Pen TDF от Krutie (@krutie) на CodePen.
Возможно, вы заметили в статическом SVG CodePen выше, что спицы — это не что иное, как прямоугольники SVG и текст, сгруппированные вместе. Я сгруппировал их вместе, так как хотел выбрать и текст, и прямоугольник для анимации.
<g v-for="stage in stages"
class="stage">
<rect x="249" y="250" width="215" height="1" stroke="#3F51B5" stroke-width="1"/>
<text transform="translate(410 245)" fill="#3F51B5" >
{{ stage.NAME }}
</text>
</g>
Мы будем отображать их в области <template>
компонента Vue, используя значения, полученные из источника данных.
Когда все 21 этап будут доступны на экране, мы установим их начальные позиции, вызвав, скажем, setSpokes()
.
// setSpokes() let stageSpokes = document.querySelectorAll(".stage") let stageAngle = 360/this.stages.length _.map(stageSpokes, (item, index) => { TweenMax.to(item, 2, { rotation: stageAngle*index, transformOrigin: "0% 100%" }, 1) }
Три ключевых элемента постановки сцены:
- Вращение
Чтобы повернуть спицы, мы просто сопоставим все элементы с classNamestage
и установим значение динамическогоrotation
, которое рассчитывается для каждой спицы. - Преобразование происхождения
Обратите внимание на значениеtransformOrigin
в приведенном выше коде, которое так же важно, как и значениеindex
, потому что «0% 100%» позволяет каждой спице вращаться от центра колеса. - сценаУгол
Это рассчитывается путем деления общего количества ступеней на 360 градусов. Это поможет нам равномерно уложить все спицы по кругу на 360 градусов.
ДОБАВЛЕНИЕ ИНТЕРАКТИВНОСТИ
Следующим шагом будет добавление события клика на каждом этапе, чтобы сделать его интерактивным и реагирующим на изменения данных — следовательно, это вдохнет больше жизни в изображение SVG!
Скажем, при нажатии на сцену/спицу выполняется goAnimate()
, которая отвечает за активацию и вращение сцены, на которую нажимают, используя параметр stageId
.
goAnimate (stageId) { // activate stage id this.activeId = stageId // rotate spokes }
Мы будем использовать DirectionalRotationPlugin… который является ключевым компонентом этой интерактивности. И да, он включен в TweenMax.
Существует три различных способа использования этого плагина. Он анимирует свойство вращения 1) по часовой стрелке, 2) против часовой стрелки и 3) по кратчайшему расстоянию, рассчитанному до места назначения.
Как вы уже догадались, мы используем третий вариант, чтобы вращать кратчайшее расстояние между текущим этапом и новым этапом.
Просмотрите CodePen выше, и вы увидите, как этап 01 постоянно перемещается по кругу, оставляя свое исходное место для нового активного этапа под углом 0 градусов.
Во-первых, нам нужно найти угол щелчка сцены и поменять местами его вращение с Stage 01 . Итак, как нам найти значение поворота сцены, по которой щелкнули? Посмотрите на диаграмму ниже.

Например, если щелкнуть этап 05 (как вы можете видеть выше), для перехода от этапа 01 к этапу 05 требуется 4-кратное значение угла.
И, следовательно, мы можем получить правильный угол, используя (Active stage Id - 1) * 17 degree,
за которым следует постфикс строки «_short», чтобы активировать плагин направленного вращения.
angle = 360/21 stages = 17 activeId = 5
new angle = (
(activeId-1)
*angle)+'_short'
= ((5-1)\*17)+'_short'
= 68
Окончательная goAnimate()
будет выглядеть примерно так:
_.map(spokes, (item, index) => { if(activeId == index+1) { // active stage TweenMax.to(item, 2, { rotation: 0+'_short', transformOrigin: "0 100%" }) } else if (index == 0) { // first stage TweenMax.to(item, 2,
{ rotation: (activeId*angle)-angle+'_short',
transformOrigin: "0 100%"
})
} else {
TweenMax.to(item, 2,
{ rotation: index*angle+'_short',
transformOrigin: "0 100%"
})
}
}) // end of map
Как только у нас будет готово заднее колесо, переднее колесо (для команды) должно следовать той же логике с парой настроек.
Вместо этапа мы получим данные команды и обновим точку регистрации атрибута transformOrigin
, чтобы включить генерацию спиц из точки регистрации, противоположной сценическому колесу.
// set team spokes map(teamSpokes, (index, key) => { TweenMax.to(index, 2, { rotation: angle*key, transformOrigin: "100% 100%"
}, 1)
})
Последний проект
Как и я, если вы написали все функции, связанные с анимацией и данными, в самих компонентах Vue. Пришло время очистить их с помощью Vuex и Mixins.

ВУЭКС
Vuex упрощает управление общими данными между компонентами и, что более важно, оптимизирует ваш код, сохраняя methods
и data()
в чистоте и порядке, позволяя компонентам только отображать данные, а не обрабатывать их.
Хуки жизненного цикла — очень подходящее место для выполнения любых HTTP-запросов. Мы получаем исходные данные в created
хуке, когда приложение Vue инициализировано, но еще не смонтировано в DOM.
Пустые переменные состояния, stages
и teams
обновляются с помощью мутаций на этом этапе. Затем мы используем наблюдатель (только один раз), чтобы отслеживать эти две переменные, и как только они обновляются, мы вызываем сценарий анимации (из mixin.js
).
Каждый раз, когда пользователь взаимодействует с этапом или компонентом команды, он связывается с хранилищем Vuex, выполняет setActiveData
и обновляет текущий этап и текущие значения команды. Вот так мы устанавливаем активные данные.
И когда активные данные установлены после обновления состояния, goAnimate
начнет анимировать (направленное вращение) спицы, используя обновленные значения.
Рекомендуемая литература : Создание пользовательских входных данных с помощью Vue.js
Миксины
Теперь, когда данные обрабатываются Vuex, мы выделим анимации GreenSock. Это предотвратит загромождение наших компонентов Vue длинными сценариями анимации. Все функции GreenSock сгруппированы в файле mixin.js
.
Поскольку у вас есть доступ к Vuex Store в Mixins, все функции GSAP используют переменные state
для анимации элементов SVG. Вы можете увидеть полнофункциональные store.js
и mixin.js
в примере CodeSandbox здесь.
Заключение
Создание интерактивной и привлекательной инфографики требует от вас аналитического подхода к данным, творческого подхода к визуальным элементам и эффективного использования используемой технологии, в данном случае — Vue.js. Вы можете в дальнейшем использовать эти концепции в своем проекте. В качестве заключительного примечания я оставлю вас с этим круговым интерактивным цветовым колесом ниже, в котором используется идея, аналогичная той, которую мы обсуждали в этой статье.
См. круговую цветовую палитру пользовательского интерфейса Pen Material, созданную Krutie (@krutie) с помощью Vue JS и GSAP на CodePen.
Без сомнения, Vue.js обладает множеством замечательных функций; мы можем создавать интерактивную инфографику всего несколькими вещами, такими как наблюдатели, вычисляемые свойства, примеси, директивы (см. пример цветового круга) и несколько других методов. Vue.js — это клей, который эффективно объединяет анимацию SVG и GreenSock, предоставляя вам широкие возможности для творчества с любым количеством тем и пользовательской интерактивностью одновременно.