Хочу поделиться примером, как при помощи нестандартных техник создать непредусмотренные виджеты на бесплатном тарифе DataLens.
Для реализации виджетов понадобится базовое знакомство с DataLens, html и python.
За основу я взял данные по заболеваемости коронавирусом за 2021-2023 годы. Ссылки на код в GitHub и дашборд можно найти в конце.
В качестве показателя использовал кол-во вылечившихся / кол-во заболевших
(соответственно, значения >= 1 считаю хорошими, < 1 плохими).
Плиточная карта
Прежде всего отвечу на вопрос "зачем изобретать велосипед, если есть обычные карты".
Да, из коробки можно наложить полигоны на карту, задать условное форматирование для отображения показателей и не мучаться с html костылями. Но есть задачи, в которых нам нужно сделать акцент на цифрах, увидеть показатели таким образом, чтобы масштаб территории не мешал восприятию.
Например, палитра с несколькими оттенками для цветового кодирования не поможет соотнести результаты крупного региона с результатами значительно меньшего по площади региона, так как помимо самих оттенков будет считываться именно размер полигона. В добавок к этому плиточная карта поможет отобразить цифры и сфокусироваться именно на них.

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

Важно, чтобы сочетания строк и колонок были уникальными для каждого региона, т.е. одна плитка соответствует одному региону.
Далее этот справочник мы превращаем в html код с инъекциями расчетов DataLens.
Берем из справочника записи с одним номером строки и распределяем регионы этой строки в элементы html в соответствии с номером колонки. Элементы, в которых не должно быть данных, форматируются таким образом, чтобы они были не видны.
Элемент, в котором должен быть регион, содержит:
название региона (можно укоротить для того, чтобы уместилось в ячейку)
условное форматирование в зависимости от расчетного значения по региону (кодом DataLens будет определяться цвет шрифта: зеленый при значении >= 1 и красный в противном случае)
само значение
кол-во вылечившихся / кол-во заболевших
Разбиение всей карты на несколько виджетов связано с тем, что есть ограничение на количество символов. Таким образом моя версия карты содержит 12 строк, т.е. 12 виджетов.
При подготовке и переносе html я при помощи python циклом проходился по словарю и формировал элементы в единый блок кода, который копировал в буфер обмена и переносил в поля DataLens.
#пример
import pyperclip
color = '#f00'
text = f"""'<div style="background-color: {color}">'+
str(sum([infected_per_day]))
+'</div>'"""
pyperclip.copy(text)
После выполнение такого коды мы получим скопированную строку, которая воспринимается DataLens следующим образом: div с заданным цветом + показатель, который считается на основе данных.

В самом DataLens для каждой строки карты я использовал виджет "Линейчатая диаграмма" со следующими настройками:
в настройках чарта скрыты все виджеты и тултипы
ось Y не имеет мер, измерений; все оси, сетка и метки отключены
ось X содержит меру
max(0)
; все оси, сетка и метки отключенымасштаб оси X вручную задан от 0 до 1, чтобы не отображать сам столбец графика
в подпись помещается html код, в настройках поля меняется разметка на HTML
После создания 12 виджетов на каждую строку карты, можно выносить их на дашборд. Получившуюся плиточную карту можно фильтровать по различным срезам.
Плюсы:
геопривязка с отсутствием эффекта масштаба и наглядное представление цифр с возможностью условного форматирования
гибкость настройки (любые цвета, формы, логика отображения)
Минусы:
чувствительность к масштабу (при сильном приближении виджет пропадает)
долгий просчет виджета (большое количество расчетов, выполняемых неоптимально)
сложность внесения изменений (например, для изменения скругления в плитках нужно вручную "пересформировать" 12 полей и внести их в каждый график)
Календарь
На следующем графике отображены данные по вылечившимся/заболевшим на каждый день года (год определяется и пересчитывается в зависимости от параметра с датой на дашборде, который может менять пользователь).
Здесь ответить на вопрос "зачем изобретать велосипед" будет сложнее. Возможно, есть задачи, где эта визуализация оказалась бы очень кстати (например, если нужно наглядно отобразить выходные и праздники или график рабочих смен), но мне было просто интересно попробовать реализовать календарь.
Приятной особенностью является завязка на дате из параметра, что позволяет пересчитать календарь на другой год при выборе другой даты пользователем (с "перемещением" плиток под настоящие даты выбранного года). То есть график строится для года, который указан в параметре-дате.
Каждый месяц является отдельным виджетом.
В структуру месяца календаря входят:
название месяца (жестко зашито наименование месяца, год зависит от параметра)
сетка из ячеек 7x6 (7 дней в неделе и максимально 6 недель могут быть затронуты в месяце)
Сама сетка состоит из 6 строк (div) с grid-template-columns: repeat(7, 1fr).
Фактически каждая ячейка имеет свой номер, который складывается из порядкового номера дня в неделе + 7 * порядковый номер недели (начиная с нуля).
Затем на основе этой сетки и даты начала месяца (которая помогает определить день недели начала месяца) рассчитывается сдвиг нумерации дней для их отображения как в календаре в этом году.
Главный смысл алгоритма в том, что в каждом графике-месяце дата параметра приводится к началу года и к нему добавляется заданное конкретно для этого виджета количество месяцев (от 0 до 11). В зависимости от дня недели старта месяца рассчитывается смещение нумерации дат. Ячейки, где дата <1 или больше даты конца месяца окрашиваются в белый, но существуют.
Цвет ячейки рассчитывается исходя из дня недели: серый - пн-пт, красный - сб-вс. Дополнительно можно реализовать логику закрашивания праздничных дней на основе справочника.
Показатель для одного дня в ячейке рассчитывается исходя из фильтрации по дате (например, сумма по всем заражениям за 21.03.2021).
Ограничения все те же, как и в случае с плиточной картой (долгий просчет, чувствительность к масштабу и сложность внесения изменений).
Дополнительно: в своих примерах я для 1 виджета использую 1 поле с html кодом, но для удобства можно отдельные куски выделять в отдельные поля:

Спасибо за внимание!
Ссылки к статье: