|
<< Click to Display Table of Contents >> Navigation: Создание окон для клиента визуализации > Рекомендации по созданию окон > Динамизация SVG элементов > Практические сценарии динамизации > Круговой прогрессбар с текстом |
Сценарий: Изменять заполнение кругового прогрессбара и значение текста.

Ссылка на ресурсы документации: https://disk.yandex.ru/d/YPWO-A0L2QglrQ
1.Создадим SVG. Пример из графического редактора Figma:
a.Создадим Frame с размерами 100x100 и добавим окружность 80x80px:

b.Уберем заливку, добавим обводку от центра на 10 и выставим цвет обводки #006398:

Почему обводка по центру?
Это связано с тем, что обводка SVG всегда рисуется от центра контура, то есть половина обводки находится внутри, а другая половина снаружи. Если выставить внутреннюю обводку, то графические редакторы изменят другие параметры SVG (например радиус), "Обводка по центру" позволяет максимально приблизить круг из графического редактора в SVG без преобразований параметров.
c.Продублируем обводку и изменим ее цвет на светло-серый #EEEEEE. Вторая обводка будет выступать в качестве фона для синей:


d.Вновь выберем синюю обводку и применим ей расширенные настройки обводки (в Figma данный раздел называется Advanced stroke settings):

e.В небольшом окне нужно выбрать Dash вместо Stroke и в поле Dash ввести значение 251,327:

Важно! После применения Figma округлила 251,327 до 251,33, значение нужно обязательно изменить в SVG коде после экспорта.
Почему именно 251,327?
I.251,327 - это длина окружности круга;
II.Длина окружности вычисляется по следующей формуле: Длина окружности = π умножить на диаметр круга;
III.В данном примере:
•π = 3,14159;
•Диаметр круга = 80.
IV.Если подставить значения в формулу, получится: 3,14159 x 80 = 251,3272;
V.Полученное число необходимо округлить до тысячных: 251,327;
Примечание: Последнее число всегда округляется в большую сторону, например, если у вас 125,6636, то нужно записать это так: 125,664.
f.Уберем белый фон и экспортируем SVG:

2.Текущий код SVG circular_progress_bar.svg:
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" stroke-dasharray="251.33 251.33"/> </svg> |
Немного отформатируем код для синего circle, чтобы удобнее было видеть все атрибуты:
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" stroke-dasharray="251.33 251.33" /> </svg> |
3.Добавим текст с помощью тега <text> и разместим его по центру (x="50" и y="50").
Также пропишем id для текста, чтобы его динамизировать: id="progress_text".
Значение текста: 100.
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" stroke-dasharray="251.33 251.33" /> <text id="progress_text" x="50" y="50">100</text> </svg> |
Добавим стили для текста с помощью тега <style> с экранированием:
•Шрифт (font-family): Arial;
•Размер шрифта (font-size): 24;
•Выравнивание по горизонтали (text-anchor): По центру;
•Выравнивание по вертикали (dominant-baseline): По центру;
•Цвет текста: #000000.
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"><![CDATA[ #progress_text{ font-family: Arial; font-size: 24px; text-anchor: middle; dominant-baseline: middle; fill: #000000; } ]]> </style> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" stroke-dasharray="251.33 251.33" /> <text id="progress_text" x="50" y="50">100</text> </svg> |
Получаем промежуточный результат:

4.Перейдем к синему <circle>:
•Добавим ему id (id="color_progress");
•В атрибуте stroke-dasharray меняем значения с 251.33 на 251.327;
•Добавляем новый атрибут: stroke-dashoffset со значением "251.327".
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"><![CDATA[ #progress_text{ font-family: Arial; font-size: 24px; text-anchor: middle; dominant-baseline: middle; fill: #000000; } ]]> </style> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle id="color_progress" cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" stroke-dasharray="251.327 251.327" stroke-dashoffset="251.327" /> <text id="progress_text" x="50" y="50">100</text> </svg> |
Как работают вместе stroke-dasharray и stroke-dashoffset?
•stroke-dasharray - первое значение данного атрибута делает обводку пунктирной, а второе значение обозначает промежутки между пунктирами. Но из-за числа 251.327 вся пунктирная обводка равна длине окружности круга. Из-за этого возникает эффект, будто пунктиров не видно.
•stroke-dashoffset - данный атрибут сдвигает начало пунктирного stroke-dasharray вдоль круга. При регулировании данного атрибута можно добиться эффекта кругового прогрессбара.
0 - полное заполнение круга, а 251.327 - пустое заполнение. Момент с инверсией обязательно нужно учитывать при создании конвертации связи.
5.Проведем отладку SVG. Изменим атрибут stroke-dashoffset на 30 и получим:
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"><![CDATA[ #progress_text{ font-family: Arial; font-size: 24px; text-anchor: middle; dominant-baseline: middle; fill: #000000; } ]]> </style> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle id="color_progress" cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" stroke-dasharray="251.327 251.327" stroke-dashoffset="30" /> <text id="progress_text" x="50" y="50">100</text> </svg> |

6.Немного развернем синий circle, чтобы он заканчивался сверху, а не справа, как сейчас.
a.Для этого добавим в circle новый атрибут, который будет отвечать за поворот: "transform="rotate(-90)"":
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"><![CDATA[ #progress_text{ font-family: Arial; font-size: 24px; text-anchor: middle; dominant-baseline: middle; fill: #000000; } ]]> </style> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle id="color_progress" cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" transform="rotate(-90)" stroke-dasharray="251.327 251.327" stroke-dashoffset="30" /> <text id="progress_text" x="50" y="50">100</text> </svg> |
b.Также переместим опорную точку в центр. Если этого не сделать, разворот произойдет от левого верхнего угла, поэтому синий прогрессбар пропадет из viewBox.
Для этого в стилях <style> нужно создать новый селектор для "#color_progress" и к нему добавить свойство "transform-origin: center;", чтобы разместить опорную точку в центр круга:
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"><![CDATA[ #color_progress{ transform-origin: center; } #progress_text{ font-family: Arial; font-size: 24px; text-anchor: middle; dominant-baseline: middle; fill: #000000; } ]]> </style> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle id="color_progress" cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" transform="rotate(-90)" stroke-dasharray="251.327 251.327" stroke-dashoffset="30" /> <text id="progress_text" x="50" y="50">100</text> </svg> |

c.SVG готов, осталось вернуть stroke-dashoffset в состояние по умолчанию: 251.327:
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"><![CDATA[ #color_progress{ transform-origin: center; } #progress_text{ font-family: Arial; font-size: 24px; text-anchor: middle; dominant-baseline: middle; fill: #000000; } ]]> </style> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle id="color_progress" cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" transform="rotate(-90)" stroke-dasharray="251.327 251.327" stroke-dashoffset="251.327" /> <text id="progress_text" x="50" y="50">100</text> </svg> |

7.Завершим последнюю настройку в XML:
Для этого сделаем импорт. В окне импорта создадим два параметра: первый параметр будет регулировать прогрессбар, а второй - текст.
a.Первый параметр для прогрессбара:
Имя параметра |
Id элемента SVG |
Атрибут элемента SVG |
value |
color_progress |
stroke-dashoffset |
b.Второй параметр для текста:
Имя параметра |
Id элемента SVG |
Атрибут элемента SVG |
text |
progress_text |
content |
Примечание: content - это уникальный атрибут, который позволяет обратиться к содержимому тега. В данном случае есть тег <text id="progress_text" x="50" y="50">100</text>.
Между открывающим (<text>) и закрывающим (</text>) тегом находится "100" и этот текст является содержимым тега, которое будет динамизироваться в MasterSCADA 4D после импорта.
Важно! Параметры добавляются строго в данном порядке, иначе после импорта свойство value будет пустым.


8.Создадим новое окно Окно 1.
Добавим в него Вертикальный ползунок и SVG "circular_progress_bar":

9.Выберем Вертикальный ползунок и с помощью зажатия ПК мыши перенесем свойство Текущее значение в SVG и свяжем со свойством value:

10.Нажмем на SVG и откроем конвертацию связей свойства value. Изменим тип конвертации на Линейно-кусочная.
Установим следующие значения:
Источник |
Приемник |
0 |
251.327 |
100 |
0 |

Закрываем окно конвертации.
Данные значения позволят менять синюю обводку пропорционально источнику от 0 до 100.
11.Возвращаемся в Вертикальный ползунок и теперь свяжем его с текстом. Конвертацию связей делать не нужно:

12.Назначаем Окно как стартовое и запускаем проект на исполнение. С помощью Вертикального ползунка регулируем прогрессбар:
a.
b.
c.
d.
e.
f.
13.В качестве бонуса создадим дубликаты файлов circular_progress_bar.svg и circular_progress_bar.xml с суффиксом "_with animation", чтобы добавить анимацию.
Для этого нужно зайти в SVG и в селектор "#color_progress" добавить еще одно свойство "transition: stroke-dashoffset 1s;", которое будет отвечать за анимацию атрибута stroke-dashoffset:
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"><![CDATA[ #color_progress{ transform-origin: center; transition: stroke-dashoffset 1s; } #progress_text{ font-family: Arial; font-size: 24px; text-anchor: middle; dominant-baseline: middle; fill: #000000; } ]]> </style> <circle cx="50" cy="50" r="40" stroke="#EEEEEE" stroke-width="10"/> <circle id="color_progress" cx="50" cy="50" r="40" stroke="#006398" stroke-width="10" transform="rotate(-90)" stroke-dasharray="251.327 251.327" stroke-dashoffset="251.327" /> <text id="progress_text" x="50" y="50">100</text> </svg> |
Импортируем SVG с анимацией и выставляем ее в Окно мнемосхемы для сравнения:

14.Готово, анимация работает:




