Зачем использовать темы
Qlik Sense — один из самых популярных BI-инструментов в мире, лидер квадрата Гартнера, который пользуется неизменной популярностью в России. Рассказывать все плюсы и минусы этого решения мы не будем — материал не об этом. Сам Qlik проприетарен, поэтому поковыряться у него внутри не так-то просто. Он использует браузер клиента в качестве своего рабочего окна, что с одной стороны ограничивает функциональность, а с другой — открывает широкие возможности для кастомизации с помощью средств CSS и определённых нотаций JSON. Как и обо всём, что касается Qlik, информации на русском языке о работе с темами Sense не так много. Что ж, восполним этот досадный пробел.
Если вы работаете с Qlik Sense, в большинстве случаев вы — сотрудник большой организации и отчёт вы делаете не для своих собственных нужд. У вас есть бизнес-заказчик, который не просто хочет получить информацию и сделать некоторые выводы, но он ещё и хочет, чтобы это было красиво. UX и UI не так сильно заботят заказчика, как красивый вид скриншота в Power Point на важном совещании. Разработчик BI-отчётности должен балансировать на тонкой грани между красотой и функциональностью своего приложения, поэтому работа с темами — один из самых простых механизмов облагородить внешний вид без ущерба юзабилити решения.
Кто мы и почему нам можно верить?
Над этим материалом работали сотрудники стрима «Мобильная аналитика и отчётность» Группы «Иннотех» Андрей Юндин, Олег Соколкин и наш руководитель Александр Антонов. Мы давно в отрасли, успели поработать и с классическим QlikView, и с Sense, видели разные боли и придумывали разные решения. Сейчас мы решили собрать материал по темам Qlik Sense, поскольку внешний вид — одна из самых волнующих бизнес-заказчика историй. Этот материал состоит из вводной информации (что такое темы, как ими пользоваться) и конкретных методов работы с объектами. Помимо этого, в тексте есть вполне реальные кейсы применения стилей, которые позволят быстро и просто придать отчётности более современный вид.
1. Вводная информация
Отчёт Qlik Sense использует для расположения объектов традиционные методы html-вёрстки документа. Это значит, что любая сущность на листе представлена тем или иным тегом, свойства которого могут быть в ограниченной степени скорректированы каскадными таблицами стилей (CSS). При этом для отображения простых элементов, таких как заголовки и таблицы, используются простые теги вроде <div>, <table> или <article>, в то время как отображением диаграмм занимаются специальные теги <canvas>, которые предназначены для создания сложных объектов визуализации с помощью JavaScript.
Тема для Qlik Sense представляет собой Extension, загружаемый в виде *.zip-архива. Внутри него располагается каскадная таблица стилей CSS, файл для управления визуализациями canvas *.json и опционально дополнительными элементами оформления (шрифты, изображения).
Корректировка темы позволяет управлять цветовой схемой отчёта, расположением объектов и в некоторых случаях их цветами. Все объекты отчёта представлены блочными и строчными html-тегами. Важное отличие: блочные теги, такие как <div>, <article> и <p>, имеют параметры ширины и высоты, в то время как строчные (<span>, <a>) имеют только параметр размера в контексте длины строки.
1.1. Почему не все цвета можно менять с помощью CSS
В обычном html-документе стили объектов могут задаваться в трёх разных местах:
С помощью тега <style>, расположенного внутри технического раздела документа <head>. Это централизованное место для хранения стилей, где с помощью специального синтаксиса указываются все селекторы, свойства и их значения. В Sense не используется.
С помощью внешних подключаемых таблиц стилей. Это те самые *.css-файлы, которые подключаются к документу и фактически применяются так же, как тег <style>, но при этом хранятся отдельно, что обеспечивает многократное использование. Именно такая таблица подключается к отчёту в тот момент, когда вы активируете для него тему.
Так называемые inline-стили. Это самый неудобный для работы вариант, когда стили прописываются для каждого тега в его описании. К примеру, <div style="color:red">. Именно inline-стили создает Qlik в тот момент, когда вы что-то меняете в редакторе отчёта.
Каждый элемент может быть описан в разных местах и по разным селекторам. К примеру, для блока <div id="mainDiv" class="textBlock"> стили можно описать сразу четырьмя селекторами или их совокупностью (на самом деле их может быть много больше, но это выходит за рамки ликбеза):
Селектором div, который будет менять стили для всех элементов div на странице.
Селектором по классу .textBlock, который будет менять стили только у тех объектов, которым присвоен класс textBlock. При этом в данной нотации селектору абсолютно неважно, будет это тег <div> или нет.
Селектором по тегу и классу div.textBlock, для которого верно всё указанное выше, но стили будут меняться только у объектов div.
И ещё селектором по id, который будет иметь вид #mainDiv.
Как браузер решает, чьими стилями пользоваться? Для этого есть таблица приоритезации. Полностью описывать мы её не будем, поэтому ограничимся замечанием о том, что id имеет высший приоритет, а все остальные селекторы становятся тем сильнее, чем подробнее они описывают элемент. У inline-свойств приоритет ещё сильнее, и для борьбы с этим нужно использовать специальную нотацию "!important", которая добавляется в конец пары свойство: значение перед символом ";".
1.2. Из чего состоит тема
Все изменения в стилевом оформлении визуализаций Qlik Sense можно корректировать в трёх местах: в самом редакторе отчёта, в файлах *.css и *.json. Стилевое оформление через редактор отчёта нельзя считать централизованным, им сложно управлять, поэтому его мы рассматривать не будем.
Тема, в свою очередь, состоит из двух основных и нескольких дополнительных файлов. Важно помнить: в темах мы не используем JS-файлы, даже если вам кажется это необходимым. Основными файлами являются *.css и *.json, дополнительными могут быть файлы шрифтов и *.qext.
1.2.1. QEXT
Файл с описанием и мета-данными темы:
Пример
{
"name": "VV Theme",
"description": "Тема для отчетов блока Риски",
"type": "theme",
"version": "1",
"author": "Oleg S."
}
1.2.2. CSS
Файл вида *.css позволяет точечно настраивать визуализацию на странице. Если вы хотите что-то изменить в конкретном блоке, вам необходимо точно подобрать css-селектор этого элемента, что удобно делать через консоль разработчика (shift+ctrl+i). Для того, чтобы ваша визуализация применилась, необходимо использовать декларацию "!important", о которой было рассказано выше.
Подключение внешних шрифтов может происходить как внутри того же CSS-файла, который описывает тему, так и через отдельный файл с описанием только шрифтов. Само подключение реализуется через правило "@font-face":
Пример
@font-face {
font-family: "GroupUI-Medium";
src: url("GroupUI-Medium.ttf") format("truetype");
font-weight: bold;
font-style: normal;
}
font-family — название шрифта, которое позднее мы сможем использовать в свойстве font-family объекта для указания шрифта.
src — адрес, по которому располагается шрифт. Если он лежит в корневой папке со стилем, то можно просто указать название файла. Если он находится в какой-либо подпапке, то необходимо использовать относительный путь.
font-weight и font-style — стандартные описания базовых свойств шрифта.
1.2.3. JSON
Этот метод является единственным действенным способом оказать влияние на диаграммы. Обратите внимание: почти все настройки цветов диаграмм корректируются через этот файл созданием палетт с подходящими цветами.
JSON-файл также является обобщающим для темы т. к. содержит информацию о подключаемых CSS-файлах. Внутри него есть раздел, внутри которого перечисляются все подключаемые стили:
Пример
"customStyles": [
{
"cssRef": "theme.css",
"classRef": "sense-theme"
},
{
"cssRef": "font.css",
"classRef": "theme-style"
}
],
2. Общие настройки
2.1. Листы приложения Qlik Sense
2.1.1. Корректировка листа отчёта
Возможна корректировка фона как с заголовком листа, так и без него:
Скрипт примера
.qvt-sheet {
background-color: red;
} /* в этом случае заголовок попадет под действие фона */
#grid {
background-color:blue
} /* В этом случае произойдет корректировка цвета фона только блока ниже заголовка */
.sheet-title-container {
background-color:green;
} /* Этот стиль меняет только свойства блока заголовка */
2.1.2. Заголовок листа
![Заголовок отчёта Заголовок отчёта](https://habrastorage.org/getpro/habr/upload_files/c2c/539/027/c2c539027161cedb703e3d99c11c7102.png)
Изображение-логотип и текст меняются из основного меню редактирования, характеристики текста — в файле *.css.
Скрипт примера
.sheet-title-text {
font-size:25pt !important;
color:blue !important;
font-weight: bold !important;
font-style:italic !important;
}
2.2. Общие настройки блоков
2.2.1. Градиент фоном
Скрипт примера
/* градиент фона для pie-chart*/
.qv-object-piechart .qv-inner-object {
background: linear-gradient(to top,#eaedf5,#ffffff) !important;
}
2.2.2. Выбор фильтров в любом цвете
![](https://habrastorage.org/getpro/habr/upload_files/be3/4e4/7a1/be34e47a1c0b144b010a79ef794a778e.png)
Необходимо выполнить 2 действия:
В JSON файл добавить:
theme.json
"customStyles": [
{
"cssRef": "dense.css",
"classRef": "qv-dense"
}
],
Создать файл dense.css, в котором прописать:
dense.css
.qv-client.qv-dense li.qv-listbox-item.ng-scope.serverSelected {
background-color: #4472c4; /*Фон при выбранном фильтре*/
border-bottom-color: #4472c4; /*Рамка фона при выбранном фильтре*/
}
.qv-client.qv-dense li.qv-listbox-item.ng-scope.selected {
background-color: #4472c4; /*Фон при выборе фильтра*/
border-bottom-color: #4472c4; /*Рамка при выборе фильтра*/
}
.qv-client.qv-dense li.qv-listbox-item.ng-scope.serverSelected:hover {
box-shadow: #4472c4; /*Не обязательно, не нашел отличий*/
}
.qv-client.qv-dense button.sel-toolbar-btn.ng-scope.sel-toolbar-confirm {
background-color: #4472c4; /*Цвет галочки, при подтверждении выбора*/
}
.qv-client.qv-dense button.sel-toolbar-btn.ng-scope.sel-toolbar-confirm:hover {
background-color: #4472c4; /*Цвет галочки, при наведении при подтверждении выбора*/
}
.qv-client.qv-dense qv-filterpane.div.state.selected {
background: #4472c4; /*Не обязательно, не нашел отличий*/
}
.qv-client.qv-dense qv-filterpane.div.state.alternative {
background: #4472c4; /*Не обязательно, не нашел отличий*/
}
.qv-object-filterpane .qv-filterpane .qv-collapsed-listbox .state.selected {
background: #4472c4; /* цвет выбранной полоски фильтра при свернутом фильтре */
}
2.3. Список объектов, доступных для корректировки из *.css
Полный список объектов
.qv-object-kpi {
}
.qv-object-linechart {
}
.qv-object-piechart {
}
.qv-object-table {
}
.qv-object-barchart {
}
.qv-object-boxplot {
}
.qv-object-combochart {
}
.qv-object-pivot-table {
}
.qv-object-treemap {
}
.qv-object-scatterplot{
}
.qv-object-gauge{
}
.qv-object-bulletchart{
}
.qv-object-waterfallchart{
}
.qv-object-histogram{
}
.qv-object-map{
}
.qv-object-container{
}
.qv-object-text-image{
}
.qv-object-mekkochart {
}
.qv-object-distributionplot {
}
.qv-object-qlik-barplus-chart {
}
.qv-object-qlik-bullet-chart {
}
.qv-object-qlik-funnel-chart-ext {
}
.qv-object-qlik-heatmap-chart {
}
.qv-object-qlik-multi-kpi {
}
.qv-object-qlik-network-chart {
}
.qv-object-qlik-radar-chart {
}
.qv-object-qlik-sankey-chart-ext {
}
.qv-object-qlik-smart-pivot {
}
.qv-object-qlik-tabbed-container {
}
.qv-object-qlik-variance-waterfall {
}
.qv-object-qlik-word-cloud {
}
.qv-object-sn-org-chart {
}
2.4. Палитра цветов для диаграмм
Корректируется *.json файл, который в нижней части имеет описание двенадцати- и четырёхцветовых палитр. В случае 12-ти цветов имеется также алгоритм добавления цветов в зависимости от количества разделов на графике.
![](https://habrastorage.org/getpro/habr/upload_files/79b/f64/573/79bf6457377550fb178a585003d2f831.png)
Скрипт примера
"palettes": {
"data": [
{
"name": "First data palette",
"translation": "12 colors",
"propertyValue": "data-palette-1",
"type": "pyramid",
"scale": [
[
"#3E5185"
],
[
"#3E5185",
"#FF8515"
],
[
"#3E5185",
"#FF8515",
"#9A64F7"
],
[
"#3E5185",
"#FF8515",
"#9A64F7",
"#D9477C"
],
[
"#3E5185",
"#FF8515",
"#9A64F7",
"#D9477C",
"#FF5A32"
],
[
"#3E5185",
"#FF8515",
"#9A64F7",
"#D9477C",
"#FF5A32",
"#4ad2ca"
],
[
"#3E5185",
"#FF8515",
"#9A64F7",
"#D9477C",
"#FF5A32",
"#4ad2ca",
"#3f7dfe"
],
[
"#3E5185",
"#FF8515",
"#9A64F7",
"#D9477C",
"#FF5A32",
"#4ad2ca",
"#3f7dfe",
"#bf67c7"
],
[
"#3E5185",
"#FF8515",
"#9A64F7",
"#D9477C",
"#FF5A32",
"#4ad2ca",
"#3f7dfe",
"#bf67c7",
"#037717"
],
[
"#3E5185",
"#FF8515",
"#9A64F7",
"#D9477C",
"#FF5A32",
"#4ad2ca",
"#3f7dfe",
"#bf67c7",
"#037717",
"#ff810a"
]
]
},
![](https://habrastorage.org/getpro/habr/upload_files/0d8/cf5/fbf/0d8cf5fbfffbc179a436ea642ab522dc.png)
Скрипт примера
"palettes": {
"data": [
{
"name": "Pie-Chart pallet",
"translation": "Pie-Chart pallet",
"propertyValue": "10",
"type": "row",
"scale": [
"#9bddfc",
"#1e4bd2",
"#99a9cd",
"#00aaff",
"#002882",
"#ca191f",
"#4cc864",
"#6b7683",
"#667eb4",
"#001144",
"#022d9a",
"#0142d3",
"#0062ff",
"#3a85ff",
"#6fa3ff",
"#a7c7ff",
"#d6e4fe",
"#b1b5bb",
"#d6d8de",
"#e5e7eb",
"#f3f4f6"
]
},
![](https://habrastorage.org/getpro/habr/upload_files/daf/da3/4dc/dafda34dc3b96f61534c96b08b108d98.png)
Скрипт примера
"palettes": {
"data": [
{
"name": "First data palette",
"translation": "12 colors",
"propertyValue": "data-palette-1",
"type": "pyramid",
"scale": [
[
"#3f7dfe"
],
[
"#5ecf70",
"#ffaf37"
],
[
"#5ecf70",
"#fb67c7",
"#4ad2ca"
],
[
"#0abbfb",
"#5ecf70",
"#ffaf37",
"#ff525c"
],
[
"#0abbfb",
"#5ecf70",
"#ffaf37",
"#ff525c",
"#e052bd"
],
[
"#0abbfb",
"#5ecf70",
"#ffaf37",
"#ff525c",
"#e052bd",
"#4ad2ca"
],
[
"#0abbfb",
"#5ecf70",
"#ffaf37",
"#ff525c",
"#e052bd",
"#4ad2ca",
"#3f7dfe"
],
[
"#0abbfb",
"#5ecf70",
"#ffaf37",
"#ff525c",
"#e052bd",
"#4ad2ca",
"#3f7dfe",
"#bf67c7"
],
[
"#0abbfb",
"#5ecf70",
"#ffaf37",
"#ff525c",
"#e052bd",
"#4ad2ca",
"#3f7dfe",
"#bf67c7",
"#037717"
],
[
"#0abbfb",
"#5ecf70",
"#ffaf37",
"#ff525c",
"#e052bd",
"#4ad2ca",
"#3f7dfe",
"#bf67c7",
"#037717",
"#ff810a"
]
]
},
3. Оформление объектов визуализации с примерами
3.1. MultiKPI
Работа со значением показателя (Value):
![](https://habrastorage.org/getpro/habr/upload_files/35d/db5/2c9/35ddb52c9b9740820af9486389c088a4.png)
Скрипт примера
.qv-object-qlik-multi-kpi .qv-object-content .value {
font-style:italic !important;
font-size: 40pt !important;
}
Работа с заголовками (Label):
![](https://habrastorage.org/getpro/habr/upload_files/33c/1fa/524/33c1fa52429d70146580516eebb2b413.png)
Скрипт примера
.qv-object-qlik-multi-kpi .qv-object-content .label {
background: linear-gradient(to top,#002882,#00aaff) !important;
color: #ffffff !important;
font-size: 12px !important;
}
3.2. KPI
У блока имеется несколько встроенных объектов:
сам блок, описываемый в CSS стилем qv-object-kpi;
подзаголовок, описываемый в json. Проблема в том, что все свойства, так или иначе задаваемые через интерфейс Qlik Sense, будут иметь больший приоритет, чем что-либо, описанное в теме.
Описание модифицированного объекта:
![](https://habrastorage.org/getpro/habr/upload_files/acf/9c1/c26/acf9c1c2610a2bcf3ac58d06979a7f68.png)
Скрипт примера
.qv-object-kpi{
border: 6px;
border-color:#000000;
border-radius: 30px;
background: #fafafa;
box-shadow: 10px 10px 30px
#bdbdbd,
-5px -5px 15px #ffffff;
};
Описание модифицированного объекта:
![](https://habrastorage.org/getpro/habr/upload_files/985/6a0/d01/9856a0d0154a1376f234e6a7c8ffab43.png)
Скрипт примера
.qv-object-kpi {
border: 4px !important;
border-color: #bdbdbd !important;
border-radius: 10px !important;
background-color: #ffffff !important;
padding: 12px !important;
}
3.3. Table
Как сделать, чтобы при наведении строка выделялась цветом:
![](https://habrastorage.org/getpro/habr/upload_files/0e0/d19/40f/0e0d1940f00f39e7c6c8f98727de0ba8.png)
Скрипт примера
tr.ng-scope:hover {
background-color: #dfecff !important;
}
3.4. Pivot table
Разукрашиваем сводную таблицу через строку. Скрываем верхние кнопки измерений:
![](https://habrastorage.org/getpro/habr/upload_files/b2f/88b/165/b2f88b1657c7ea547c9c66db8de15322.png)
Скрипт примера
/* раскрасить всю таблицу через одну строчку*/
tr.ng-scope:nth-child(2n) {
background-color: #dfecff;
}
/* так как в данном случае три строки измерения то строки Факт/План и 2021/янв/фев... также разукрашиваются, поэтому закрашиваем строки в белый цвет
Если у вас одно измерение, то данные строки не нужны*/
Tr.ng-scope:nth-child(2) {
background-color: #fff;
}
Tr.ng-scope:nth-child(4) {
background-color: #fff;
}
/* убираем верхние кнопки измерений*/
[tid="meta.rows"], [tid="meta.columns"]
{
display:none;
}
3.5. Waterfall
Стоит сказать про особенности Watrefall. Из-за особенностей QS, при использовании водопада съезжает заголовок, если не написать условие padding для заголовка водопада:
![](https://habrastorage.org/getpro/habr/upload_files/a2a/d7a/4ce/a2ad7a4ce0f418340a69147cde74e92f.png)
Рекомендуемые параметры
/*
Для графика waterfall отступы текста пропадают, поэтому необходимо их добавлять отдельно
*/
.qv-object-waterfallchart .qv-object-header {
padding: 0px 12px 10px !important;
}
Стандартные цвета водопада описываются в JSON.
Для примера здесь указаны цвета для positiveValue / negativeValue / subtotal /bridge.
JSON
"waterfallChart": {
"backgroundColor": @lightt",
"title": {
"main": {
"color": @defaultt",
"fontSize": @font-normall",
"fontFamily": @font-family-subtitlee"
},
"subTitle": {
"color": @defaultt",
"fontSize": @font-normall",
"fontFamily": @font-family-subtitlee"
},
"footer": {
"color": @defaultt",
"fontSize": @font-normall",
"fontFamily": @font-family-subtitlee",
"backgroundColor": @lightt"
}
},
"axis": {
"title": {
"fontSize": @font-normall",
"fontFamily": @font-family-subtitlee",
"color": @defaultt"
},
"label": {
"name": {
"color": @defaultt",
"fontSize": @font-size-smalll",
"fontFamily": @font-family-subtitlee"
}
},
"line": {
"major": {
"color": @defaultt"
},
"minor": {
"color": @defaultt"
}
}
},
"legend": {
"label": {
"fontSize": @font-normall",
"fontFamily": @font-family-subtitlee",
"color": @defaultt"
}
},
"label": {
"value": {
"fontSize": @font-size-smalll",
"fontFamily": @font-family-subtitlee"
}
},
"value": {
"color": {
"default": @defaultt",
"dark": @darkk",
"light": @lightt"
}
},
"shape": {
"positiveValue": {
"fill": "4472c4"
},
"negativeValue": {
"fill": "#d2d2d2"
},
"subtotal": {
"fill": "#4472c4"
},
"bridge": {
"stroke": "#333333"
}
}
},
4. Как быстро применить стиль CSS, не создавая новую тему (Multi KPI)
Для того, чтобы использовать CSS, не создавая тему, можно воспользоваться стандартным инструментом Qlik Sense, который поддерживает редактирование CSS - Multi KPI.
![](https://habrastorage.org/getpro/habr/upload_files/45f/1bf/4a0/45f1bf4a0b163474bd2803b422092081.png)
Необходимо добавить его на лист (пункты 1—3 на рисунке).
Необходимо прописать в меру какой-либо показатель, можно просто поставить 1 (пункт 4 на рисунке).
Прописать стиль CSS в специальное окно (пункт 5 на рисунке). В данном случае добавили стиль для стандартного объекта KPI. Скруглили углы, добавили тень.
Используемый код в данном примере
.qv-object-kpi {
border: 4px !important;
border-color: #bdbdbd !important;
border-radius: 20px !important;
background-color: #ffffff !important;
padding: 12px !important;
box-shadow: 10px 10px 30px
#bdbdbd !important;
}
.qv-object-qlik-multi-kpi {
display:none;
}
Для скрытия объекта Multi KPI на листе используем этот код
.qv-object-qlik-multi-kpi {
display:none;
}
Важные моменты:
Для того, чтобы тема работала, необходимо добавить какую-либо меру в показатель, без меры CSS стили не применяются. Можно добавить просто цифру 1 как меру.
Для того, чтобы инструмент работал, необходимо его куда-то поместить на лист (он обязательно должен присутствовать на нём, минимум — клетка 1х1.
Все стили CSS применяются только к листу, где расположен этот объект. Если необходимо сделать на другие листы такие же стили, нужно его скопировать. Либо просто создать свою тему.
Если какое-то свойство не работает, можно попробовать в конце свойства, перед точкой запятой написать !important.
Элемент немного тормозит, если печатать код CSS прям внутри него. Поэтому, как совет, лучше прописать код в текстовом редакторе, а потом вставлять его сюда. Либо печатать медленно, чтобы каретка не улетала в конец.
5. Как может помочь режим разработчика Qlik Sense
Этот режим не только и не столько связан с темами, но не упомянуть о нём нельзя. Включается он так: необходимо зайти на страницу отчёта, приступить к его редактированию и в адресной строке изменить окончание на /options/developer/.
Таким образом, в конце адресной строки у нас будет окончание либо /state/edit/options/developer, что можно считать избыточным, либо просто /options/developer. Пример:
![](https://habrastorage.org/getpro/habr/upload_files/52a/3e9/463/52a3e94631b94dc83b8063a6dbda87f9.png)
После этого у ПКМ любого объекта появится новый пункт: Developer. Этот пункт содержит информацию об ID объекта и ряде его свойств (не CSS). Из него же можно попасть в меню Single Configuration, протестировать экспорт объекта в PDF (полезная функция для предыдущего шага) и так далее.
![](https://habrastorage.org/getpro/habr/upload_files/f2b/a5a/06f/f2ba5a06ff4cdc553d4d0a262a1831dc.png)
Сам по себе этот id нам мало что дает, поскольку в явном виде он не используется, но, во-первых, он может быть значением некоторых атрибутов, во-вторых, часть id некоторых вложенных элементов. Здесь нельзя составить подробное описание работы с каждым видом элементов, поэтому ограничимся общим вариантом.
Для примера возьмем объект KPI. С точки зрения HTML-кода он обёрнут в тег article, которому мы обычно и меняем свойства через класс .qv-object-kpi. Разумеется, это будет касаться всех объектов этого типа, что не всегда нам подходит. Мы можем посмотреть id конкретного объекта, который нас интересует. Пример на скриншоте выше, полный id выглядит как 0d341278-321e-4b4b-9056-81dcb716d000.
Попробуем посмотреть, где он встречается у нашего объекта KPI. Помимо элементов-потомков, мы видим в среди атрибутов тега следующее:
HTML тега article
<article class="qv-object qvt-visualization qv-mode-edit qv-can-take-snapshot qv-layout-xsmall qv-object-kpi" ng-class="classList" tid="qv-object-kpi" aria-labelledby="0d341278-321e-4b4b-9056-81dcb716d333_type 0d341278-321e-4b4b-9056-81dcb716d333_title 0d341278-321e-4b4b-9056-81dcb716d333_noTitle 0d341278-321e-4b4b-9056-81dcb716d333_content">
Обращаем внимание на атрибут aria-labelledby. В явном виде id там упоминается несколько раз, но с постфиксами, да ещё и в кастомном атрибуте. Здесь на помощь придут широкие возможности современного CSS. Мы можем написать следующий селектор:
для theme.css
article[aria-labelledby*='0d341278-321e-4b4b-9056-81dcb716d333_content'] {
border-color:red !important;
background-color:green !important;
}
Этот селектор ищет среди всех тегов article элементы с атрибутом aria-labelledby, в значении которого В ЛЮБОМ МЕСТЕ (это важно) содержится наш id. Важно использовать именно '*=', поскольку есть также варианты поиска только в начале или конце значения. Как итог, имеем изменённые стили только у одного элемента.
Конечно, вы всегда можете использовать уникальные css-селекторы на основе положения элемента на веб-странице (речь про nth-child), но эти механизмы не гарантируют сохранения правил при изменении структуры. ID элемента, конечно, тоже может меняться, но это внесение изменений не в визуальную, а скорее в функциональную часть.
6. Как сочетаются темы, Nprinting и выгрузка в PDF
Один из самых распространённых кейсов в работе с темами — проблемы с выгрузкой отчёта в PDF посредством штатного инструмента выгрузки или Nprinting. Почти все свойства CSS без проблем применяются при выгрузке отчётов кроме одного, которое гарантированно сломается: box-shadow. Судя по нашим исследованиям, это связано с изменением внешних габаритов объекта.
6.1. Выгрузка PDF штатными средствами
Проходит без проблем кроме блоков, которые используют свойство box-shadow. Если такое свойство есть у любого экспортируемого объекта, экспорт не состоится. При этом настройки прочих объектов, не участвующих в экспорте, никак не влияют — у соседнего блока box-shadow может быть, но пока мы не решим выгрузить его в PDF, никаких проблем не будет. Все прочие CSS-свойства работают аналогично представлению в веб-версии.
6.2. Выгрузка в Nprinting
Для того, чтобы передать пользовательскую тему в Nprinting, необходимо при импорте выбрать соответствующий чекбокс. Тогда при импорте объектов из дашборда никаких проблем возникнуть не должно. Если у какого-то из импортируемых объектов будет использовано свойство box-shadow, отчёт не соберётся.
Вместо послесловия
Данное руководство — не полный мануал или подробный cookbook. Оно содержит базовые приёмы, которые позволят вам быстро приступить к работе с темами, и указывает на некоторые неочевидные нюансы. Сегодня работа с постоянно обновляющимся CSS ограничена в общем случае версией браузера, которая установлена у клиента, и версией сервера Sense, который отвечает за выгрузку отчётов во внешние форматы, например PDF.