Время прочтения: 5 мин.
Все задачи, о которых пойдет речь далее, решаются при помощи функции dual():
Dual(text, number)
где
text – значение, которое будет отображаться (например, подпись данных на точке графика).
number – значение, которое будет использоваться в качестве реального значения для построения графика.
Чтобы было проще понять, построю гистограмму с выражением:
Получается такой график:
На подписи данных показано значение 50, но для построения столбца использовано значение 1 – это видно по оси слева.
Задача №1
Требуется на одной горизонтальной гистограмме отобразить столбцы с их значениями (цвет значений оставить черным), рядом проставить цифры с динамикой, причем расположить в зависимости от длины столбца, а, так же, выделить цветом в зависимости от знака (зеленым – положительные, красным – отрицательные), вот так:
На первый взгляд, данная задача легко решается при помощи формулы dual(), но остается загвоздка в цветах – в QV нельзя устанавливать разный цвет текста для отдельных цифр, вычисляемых в одном выражении (Expression), то есть либо все цифры – и факт, и динамика будут либо черными, либо с условным форматированием, а ТЗ у нас другое.
Мое решение:
п.1 Создаю первую гистограмму со значениями факта, с формулой Sum():
п.2 Создаю вторую диаграмму для динамики, с формулой dual():
Для второй диаграммы:
— на вкладке Expressions оставляю галочки Invisible (для того, чтобы не отображались столбцы), Bar (чтобы не получить сообщение «All expression disabled»), Values on Data Points (для показа цифр динамики). В свойствах выражения Text Color прописываю формулу условного форматирования:
Sum({<Календарь.Дата={'$(v1004MaxDateSum)'}>}[Количество терминалов])>Sum({<Календарь.Дата={'$(v1004_1m_Date)'}>}[Количество терминалов]),
Green(),
rgb(255,0,0)
)
где
v1004MaxDateSum – переменная для выбора значений текущего периода
v1004_1m_Date – переменная для выбора значений предыдущего периода,
Green() – цвет, если текущее значение больше предыдущего
Rgb(255,0,0) – цвет, если текущее значение меньше предыдущего.
— Убираю отображение всех осей и легенды, чтобы остались только значения
— Для фона диаграммы устанавливаю полную прозрачность (Вкладка Colors – Область Frame Background – Transparency)
Смотрю, что получилось:
п.3 Накладываю вторую диаграмму поверх первой – готово.
В моем случае цифры динамики иногда накладывались на цифры факта, поэтому я задал значение смещения в первую часть dual():
При помощи этой строки вставляем пробелы перед значением динамики, в количестве равном длине вычисляемого значения факта, и отодвигаем отображаемую цифру правее от факта.
Задача №2.
При построении графиков подписи точек близких по значению выражений будут накладываться друг на друга, из-за чего может быть трудно понять, что там вообще написано, да и с визуальной точки зрения выглядит некрасиво.
Решение:
п1. Создаю выражение, которое будет дублировать подписи данных линии «Первичка», но сам график факта будет смещен на 0,3 (30%) в зависимости от условия:
п.2 Создаю выражение, которое будет дублировать подписи данных линии «Вторичка», но сам график факта будет смещен на 0,3 (30%) в зависимости от условия:
На самом деле п.2 не всегда обязателен, иногда бывает достаточно смещения только для одного выражения.
п.3 Графики выражений из п.1 и п.2 делаю прозрачными (Invisible на вкладке Expressions)
п.4 Для выражений «Первичка» и «Вторичка» убираю подписи данных (Values on Data Points)
Получаем график:
Но на нашем графике всего два выражение, а что делать если их три или четыре? Конечно, использовать dual()! Однако, есть тонкости — возможно, я разберу кейс с тремя выражениями в следующих постах.
Задача № 3.
Сделать лист бокс для выбора квартала с наименованием периодов в формате «№кв КВ ГОД» — например «3 КВ 2021», при том, что в исходных данных указана только дата в формате ДД.ММ.ГГГГ.
В исходных данных поле с отчетным периодом — Multifact.period_end
Решение:
Если просто сделать листбокс с указанном выше полем, то получим такой результат:
Решение:
В качестве поля для листбокса указываем Expression:
dual(Ceil(Month(Multifact.period_end)/3) & ' КВ ' & Year(Multifact.period_end), QuarterName(Multifact.period_end))
где
Ceil(Month(Multifact.period_end)/3) & ‘ КВ ‘ & Year(Multifact.period_end) – значение, которое будем видеть в лист бокс.
QuarterName(Multifact.period_end) – фактические значения, которые будут фильтроваться при выборе квартала и участвовать в сортировке. Функция QuarterName() нужна, чтобы отсечь лишние даты, которые не являются окончанием квартала.
Итог:
Как мы видим, функция dual() является отличным инструментом, для решения задач, которые на первый взгляд являются невыполнимыми. Ее применение не ограничивается представленными мною задачами, при должном уровне креативности и изобретательности она может быть применена в совершенно неожиданных местах. Надеюсь, что моя статья поможет разработчикам разобраться с принципами работы функции dual() и активно применять ее при создании своих DB.