У Радислава Гандапаса есть отличная книга Полная Ж. В ней говорится о том, как оценить направления своей жизни, и как разработать план развития. Мне захотелось создать инструмент, который будет в моем смартфоне и поможет составить мой радар.  Исходный код туториала и демо можно посмотреть здесь. Этот проект небольшой, поэтому писать мы будем сразу в REPL, онлайн редакторе svelte. Если вам по душе локальная разработка, то можете воспользоваться webpack или rollup шаблонами svelte. Как альтернативу локальной разработке могу посоветовать онлайн инструмент codesandbox. Если вы используете VScode, то рекомендую установить плагин svelte-vscode Итак, открываем REPL и начинаем Сейчас у нас есть файл App.svelte, это точка входа в приложение. Компоненты Svelte стилизуются в теге style, как в обычном html. При этом вы получаете изоляцию стилей на уровне компонента. Если необходимо добавить глобальные стили, которые будут доступны "снаружи" объекта, то нужно воспользоваться директивой :global(). Добавим стили и создадим контейнер для нашего приложения. Создадим компонент Radar.svelte. Это будет SVG элемент, в котором мы будем рисовать наше колесо. Javascript код в компоненте Svelte помещается в тег script. Импортируем наш Radar.svelte в App.svelte и отрисуем его. Сам радар будет состоять из секторов, соответствующих жизненным аспектам. Каждый сектор имеет свой индекс  Каждый сектор состоит из сетки, которая, в свою очередь, является сектором с меньшим размером.  Для отрисовки сектора нам нужно знать координаты трех вершин.  Вершина А всегда с координатами [0, 0], так как начало координат будет по центру нашего радара. Для нахождения вершин В и С воспользуемся функцией из отличного туториала по гексагональным сеткам. На вход функция получает размер сектора и направление, а возвращает строку с координатами 'x,y'.
Создадим файл getHexCorner.js, куда поместим нашу функцию getHexCorner(size, direction) Теперь создадим компонент сектора Sector.svelte, который рисует сетку. Нам нужен цикл из 10 шагов. В теле компонента svelte не умеет реализовывать цикл for, поэтому я просто сделал массив grid, по которому буду итерировать в директиве #each. Если у вас есть идеи, как это можно сделать элегантней, напишите об этом в комментариях. Импортируем и отрисуем сектор в компоненте Radar.svelte. Теперь наше приложение отображает 1 сектор.  Чтобы отрисовать весь радар, необходимо знать перечень секторов. Поэтому займемся созданием хранилища состояния. Мы будем использовать кастомный стор, в котором реализуем логику обновления состояния. Вообще, это обычное хранилище Svelte, которое завернуто в функцию. Это позволяет защитить хранилище от изменений, предоставив набор доступных действий. Мне нравится этот подход тем, что структура данных и логика работы с ними находятся в одном месте. Создадим файл store.js Нам потребуются два хранилища: Теперь импортируем созданный стор в компонент Radar.svelte и добавим логику отрисовки полного радара.  Немного тонкостей директивы #each. Мы используем имя переменной $radar. Директива $ дает понять компилятору Svelte, что наше выражение является хранилищем, и он создает подписку на изменения. Переменная direction хранит индекс текущей итерации, по нему мы будем задавать направление нашего сектора. Выражение (sector.name) указывает svelte на id объекта в итерации. Аналог key в React. Сейчас наша сетка выглядит вот так  Осталось подготовить сектор к работе с событиями нажатия и перетаскивания.
Событие touchmove, в отличие от mousemove, срабатывает только на элементе, на котором началось. Поэтому мы не сможем отловить момент, когда указатель переместился на другой сектор. Для решения этой проблемы в разметке элемента  мы будем хранить текущее имя (name) сектора и его значение (value). В момент события будем определять, какой сектор находится под курсором, и изменять его значение.
 Обратите внимание, что Svelte умеет разворачивать конструкцию {varName} в varName={varName}. Это очень упрощает прокидывание свойств. Если мы добавим в нашем сторе (store.js) значение, отличное от нуля, то должен получится такой результат:
 Пришло время вдохнуть жизнь в наш радар, создадим обработчик, который на вход принимает ноду, а внутри производит обработку событий касания и мыши. Теперь просто добавим наш обработчик в svg элемент радара через директиву use: Радар теперь реагирует на клики и перетаскивания.
 Добавим подписи для секторов и описание Радар должен выглядеть так.  Я немного расширил функционал радара, добавил хранение данных в localStorage и составление плана действий. Вы можете попробовать приложение life-checkup, исходный код доступен в gitlab.  CTO