[Перевод] Создание динамических древовидных карт с помощью SVG и Vue.Js

внешний интерфейс Программа перевода самородков SVG Vue.js внешний фреймворк

Создание динамических древовидных карт с помощью SVG и Vue.Js

В этой статье вы узнаете, как я создал динамическую древовидную карту, в которой используется SVG (масштабируемая векторная графика) для рисования кубических путей Безье и Vue.js для реагирования на данные.

До начала,Давайте сначала посмотрим на демо.

Опираясь на мощь фреймворков SVG и Vue.js, мы можем легко создавать управляемые данными, интерактивные и настраиваемые диаграммы и инфографику.

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

Мы сначала научимся создавать кубические кривые Безье, а потом попробуем найти координаты по обтравочным маскам<svg>элемент доступенxа такжеyточка.

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

SVG

Как образуются кубические кривые Безье?

Кривая, которую вы видите в приведенной выше демонстрации, называется кубической кривой Безье. Я выделил каждую часть этой структуры кривой ниже.

Он имеет в общей сложности 4 пары координат. Первая пара координат -(x0, y0)-- начальная точка привязки, а последняя пара координат --(x3, y3)-- является конечным якорем, указывающим, где путь завершен.

Две пары координат в середине:

  • Контрольная точка Безье №1(x1, y1)а также
  • Контрольная точка Безье № 2(x2, y2)

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

Давайте поместим эти четыре координаты в синтаксис SVG.<path>в элементе.

// 三次贝塞尔曲线的路径语法

<path D="M x0,y0  C x1,y1  x2,y2  x3,y3" />

буквы в грамматикеcПредставляет кубическую кривую Безье. маленькийcуказывает относительные значения, а верхний регистрCпредставляет собой абсолютное значение. я использую абсолютное значениеCдля создания этого графика.

достичь симметрии

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

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

Присвоим этой переменной фактическое значение. Таким образом, вы также можете рассчитать координаты пути.

size = 1000

найти координаты

Прежде чем мы сможем найти координаты, нам нужно создать новую систему координат!

Система координат и viewBox

<svg>элементальviewBoxАтрибут важен, потому что он определяет пользовательскую систему координат SVG. вкратце,viewBoxОпределяет местоположение пользователя пространства и размеры для рисования SVG.

viewBoxОн состоит из четырех чисел, и порядок должен быть последовательным -min-x, min-y, width, height.

<svg viewBox="min-x min-y width height">...</svg>

мы определили ранееsizeПеременная будет управлять этой системой координат.widthа такжеheight.

Позже в разделе Vue.jsviewBoxбудет привязан к вычисляемому свойству для заполненияwidthа такжеheight,а такжеmin-xа такжеmin-yВ этом случае всегда ноль.

Обратите внимание, что мы не использовалиSVG-элементсебяwidthа такжеheightАтрибуты. Потому что мы установим его позже через CSS<svg>изwidth: 100%а такжеheight: 100%, чтобы он адаптивно заполнил всю область просмотра.

Теперь, когда пользовательское пространство/система координат всего графа готово, давайте посмотримsizeКак переменные различаются при использовании%значение, помогающее рассчитать координаты.

Постоянные и динамические координаты

Diagram Concept

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

Вертикальная высота делится на две части:topHeight(size20%) иbottomHeight(sizeостальные 80%). Ширина по горизонтали делится на две части - соответственноsize50%.

Такие круговые координаты (halfSize, topHeight) очевидно. круглыйradiusсвойство установлено наtopHeightполовина имеющегося пространства очень подходит.

Теперь давайте посмотрим на координаты пути...

  • x0, y0- первая пара анкеровВсегда оставаться без изменений. здесь,x0это графsizeцентр,y0это вертикальная точка, где круг останавливается (Таким образом, добавляется радиус) и является начальной точкой пути.
    =(50% 的 size, 20% 的 size + radius)
  • x1, y1- Контрольная точка Безье 1, для всех путейОстается неизменной. Учитывая симметрию,x1а такжеy1всегда графикsizeполовина . знак равно(50% 的 size, 50% 的 size)
  • x2, y2- контрольная точка Безье 2, гдеx2Укажите, какая сторона образует кривую и для каждого путиДинамический расчет. такой же,y2это графsizeполовина .
    = (x2, 50% 的 size)
  • x3, y3- Последняя пара опорных точек, указывающая, где заканчивается рисунок пути. здесь,x3подражатьx2значение, которое рассчитывается динамически.y3занятыйsize80%.
    = (x3, 80% 的 size)

См. общий синтаксис пути ниже после объединения приведенных выше вычислений. чтобы выразить%, я просто выразился%Значение делится на 100.

<path d="M size*0.5, (size*0.2) + radius  
         C size*0.5,  size*0.5
           x2,        size*0.5
           x3,        size*0.8"
>

Примечание: по всей логике кода%Выбор , может на первый взгляд показаться субъективным, но это правильное соотношение, выбранное для достижения симметрии. Как только вы поймете цель построения этой диаграммы, вы сможете попробовать свои собственные.%значение и проверить разные результаты.

Следующая часть посвящена поиску оставшихся координат.x2а такжеx3Значение - позволяет динамически формировать несколько извилистых путей на основе их индексов массива.

В зависимости от количества элементов в массиве доступное горизонтальное пространство должно быть разделено на равные части так, чтобы каждый путь былx-axisчтобы получить такое же количество места.

В конечном итоге формула должна работать для любого количества элементов, но для целей этой статьи я использовал 5 элементов массива:[0,1,2,3,4]. Это означает, что я нарисую 5 кривых Безье.

Найти динамические координаты (x2 и x3)

Во-первых, я будуsizeРазделите на количество элементов, которое является длиной массива, и назовите егоdistance-- как расстояние между двумя элементами.

distance = size/arrayLength
// distance = 1000/5 = 200

Затем я перебираю каждый элемент в массиве и помещаю егоindexзначение, умноженное наdistance. Для простоты описания я используюxвыражатьx2а такжеx3.

// value of x2 and x3
x = index * distance

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

Как видите, расположение координат правильное, но не очень симметричное. Кажется, что элементы слева содержат больше элементов, чем элементы справа.

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

Чтобы исправить это, давайте вернемся к переменнымdistance- Для данной сцены его значение равно 200. я просто даюxдобавлено сноваполовина расстояния.

x = index * distance + (distance * 0.5)

Приведенная выше формула означает, что я нашелdistanceсередина финалаx3Координаты помещаются туда, а кривая Безье №2 корректируется дляx2.

существуетx2а такжеx3добавить координатыполовина расстояния, для нечетных и четных элементов массива.

слой маски

Чтобы сделать форму маски круглой, яmaskэлементопределениевзял одинcircle.

<defs>
  <mask id="svg-mask">
     <circle :r="radius" 
             :cx="halfSize" 
             :cy="topHeight" 
             fill="white"/>
  </mask>
</defs>

Далее используйте<svg>в элементе<image>тег как контент, я используюmaskсвойство для привязки изображения к<mask>элемент (уже созданный в приведенном выше коде).

<image mask="url(#svg-mask)" 
      :x="(halfSize-radius)" 
      :y="(topHeight-radius)"
...
> 
</image>

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

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

Динамический SVG с Vue.js

До сих пор мы понимали природу кривой Безье и то, как она работает. Следовательно, у нас есть концепция статического изображения SVG. Используя Vue.js и SVG, мы теперь будем управлять диаграммой с данными и преобразовывать ее из статической в ​​динамическую.

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

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

В этом разделе мы узнаем о следующих ключевых темах.

  • Привяжите SVG viewBox
  • Вычислить координаты пути SVG
  • Два варианта реализации пути Безье
  • панель конфигурации
  • Домашнее задание ❤

Привяжите SVG viewBox

Во-первых, нам нужна система координат для рисования внутри SVG. вычисляемое свойствоviewboxбуду использоватьsizeПеременная. Он содержит четыре значения, разделенных пробелами — он подается в<svg>элементальviewBoxАтрибуты.

viewbox() 
{
   return "0 0 " + this.size + " " + this.size;
}

В SVG,viewBoxАтрибутыужеИспользуйте верблюжий регистр.

<svg viewBox="0 0 1000 1000">
</svg>

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

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

Вычислить координаты пути SVG

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

Если вы измените размер SVG, эти значения вычисляются заново. Имея это в виду, вот список из пяти значений, необходимых для рисования кривой Безье.

  • верхняя высота —size * 0.2
  • нижняя высота —size * 0.8
  • ширина -size
  • половинный размер -size * 0.5
  • расстояние —size/arrayLength

На данный момент у нас осталось только два неизвестных значения, а именноx2а такжеx3, у нас есть формула для определения их значений.

x = index * distance + (distance * 0.5)

найти вышеперечисленноеx, нам нужно преобразоватьindexВведите формулу для каждого пути. так……

Уместно ли здесь использовать вычисляемые свойства? Конечно не подходит.

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

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

В случае, описанном в этой статье, мы не используем Vuex. Но даже в этом случае у нас остается два варианта.

Выбери один

Мы можем определить функцию, где мы преобразуем массивindexПередайте как параметр и верните результат. Если вы хотите использовать это значение в нескольких местах шаблона, выберитеBit cleaner.

<g v-for="(item, i) in itemArray">
  <path :d="'M' + halfSize + ','         + (topHeight+r) +' '+
            'C' + halfSize + ','         + halfSize +' '+    
                  calculateXPos(i) + ',' + halfSize +' '+ 
                  calculateXPos(i) + ',' + bottomHeight" 
  />
</g>

Метод calculateXPos() будет оцениваться при каждом вызове. И этот метод принимает индекс -i-- как параметр (код ниже).

<script>
  methods: {
    calculateXPos (i)
    {
      return distance * i + (distance * 0.5)
    }
  }
</script>

Ниже приведен результат выполнения варианта 1 на CodePen.

Option 1 - Bezier Curve Tree Diagram with Vue Js

вариант второй

Лучше, мы можем извлечь этот маленький тег по пути SVG в свои подкомпоненты и будетindexПередайте его как атрибут — конечно, есть и другие обязательные атрибуты.

В этом примере мы даже можем использовать вычисляемые свойства, чтобы найтиx2а такжеx3.

<g v-for="(item, i) in items"> 
    <cubic-bezier  :index="i" 
                   :half-size="halfSize" 
                   :top-height="topHeight" 
                   :bottom-height="bottomHeight" 
                   :r="radius"
                   :d="distance"
     >
     </cubic-bezier>
</g>

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

<clip-mask :title="title"
           :half-size="halfSize" 
           :top-height="topHeight"                     
           :r="radius"> 
</clip-mask>

панель конфигурации

Config Panel

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

Хотите знать, как выглядит код для Варианта 2? Ссылка ниже — это код, использующий Вариант 2 на CodePen.

Option 2 - Bezier Curve Tree Diagram with Vue Js

Репозиторий GitHub

Наконец, вот один для васGitHub Repo, вы можете просмотреть элемент (используйте вариант 2), прежде чем перейти к следующему разделу.

домашнее задание

Попробуйте создать такой же график в вертикальном режиме на основе логики, представленной в этой статье.

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

С помощью Vue.js график можно расширить за счет дополнительных функций, таких как:

  • Создайте переключатель для переключения между горизонтальным и вертикальным режимами.
  • Пути можно анимировать с помощью GSAP.
  • Управляйте свойствами контура (например, цветом и шириной обводки) с панели конфигурации.
  • Сохранение и загрузка диаграмм в виде изображений/PDF-файлов с использованием сторонних библиотек инструментов.

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

удачи!

Суммировать

<path>— один из многих мощных элементов SVG, поскольку он позволяет создавать графики и диаграммы с высокой точностью. В этой статье мы узнали, как работают кривые Безье и как создать собственное приложение для построения графиков.

Настройка с использованием подхода, основанного на данных, используемого современными средами JavaScript, всегда сложна, но Vue.js делает это очень легко и также может выполнять простые задачи, такие как манипулирование DOM. Таким образом, как разработчик, вы можете мыслить с точки зрения данных даже при работе над проектами с очевидными визуальными эффектами.

Я понял, что для создания этой сложной диаграммы требуются некоторые простые концепции Vue.js и SVG. Если вы не готовы, я предлагаю вам прочитать оСоздавайте интерактивную инфографику с помощью Vue.jsСодержание. Будет намного легче вернуться к этой статье после прочтения этой статьи. ❤ Это домашнее заданиеОтвечать.

Я надеюсь, что вы узнали что-то из этой статьи и почувствовали радость от моего письма в то время, пока читали ее.

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


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.