Версия: 2.0

Работа с Deneb в PBIR

Формат Power BI Enhanced Report Format (PBIR) становится стандартным для отчётов Power BI. Это руководство объясняет, что нужно для работы возможностей Deneb, если вы вручную редактируете или программно создаёте визуалы, используете языковую модель или другой инструмент для создания отчётов либо сама языковая модель читает эту страницу как инструкцию.

Помимо PBIR, сведения помогут понять внутреннее устройство Deneb и создавать темы отчётов, содержащие его визуалы.

Краткая справка

Рекомендуется прочитать руководство целиком. Если нужны только минимальные свойства для работающего визуала Deneb в PBIR, они приведены ниже.

Минимальное определение визуала Deneb

В файле visual.json экземпляра визуала:

Путь Значение
visual.visualType "deneb7E15AEF80B9E4D4F8E12924291ECE89A"
visual.objects.vega[0].properties.jsonSpec Спецификация Vega/Vega-Lite, преобразованная в строку и заключённая в ''.
visual.objects.vega[0].properties.jsonConfig "'{}'"

Проверка конфигурации PBIR

Перед загрузкой отчёта:

  1. Убедитесь, что все строки JSON правильно экранированы.
  2. Проверьте суффикс D у целочисленных значений.
  3. Убедитесь, что текстовые значения заключены в одинарные кавычки внутри поля Value.
  4. Проверьте, что логические значения заданы литералами true или false.

Подробнее о типах см. в разделе «Задание свойств».

GUID визуала

Каждый визуал Power BI имеет уникальный идентификатор GUID, определяющий его тип. Для сертифицированной версии Deneb из AppSource это:

deneb7E15AEF80B9E4D4F8E12924291ECE89A

GUID также указывает Power BI, где искать обновления. Если идентификатор совпадает с опубликованным визуалом AppSource, Power BI попытается обновить его при появлении новой версии. При использовании PBIR/PBIP код визуала не нужно включать в ресурсы PBIP и хранить под контролем версий: Power BI может получить его непосредственно из AppSource.

Другие варианты визуала

Для других вариантов Deneb используются следующие GUID:

  • Standalone: STANDALONEdeneb7E15AEF80B9E4D4F8E12924291ECE89A.
  • Alpha Channel: ALPHAdeneb7E15AEF80B9E4D4F8E12924291ECE89A.
  • Beta Channel: BETAdeneb7E15AEF80B9E4D4F8E12924291ECE89A.

Эти варианты не связаны с AppSource и требуют дополнительной настройки: код .pbiviz нужно включить в ресурсы PBIP.

Подобно прежнему формату .pbix для отчётов Power BI, файл .pbiviz — сжатая папка. Её можно открыть, например, в 7-Zip и извлечь содержимое для просмотра. Распаковка .pbiviz в /CustomVisuals/{GUID}/ создаёт необходимую структуру для включения визуала в PBIR/PBIP.

Описание возможностей визуала

Capabilities — специальные метаданные, фактически задающие соглашение визуала с Power BI: поддерживаемые роли данных и их организация, параметры форматирования и интерактивные возможности. В PBIR это описание имеет формат JSON. Power BI обращается к нему при добавлении визуала в отчёт, чтобы определить, как интегрировать его в среду отчёта.

Когда вы добавляете и настраиваете визуал, в JSON его экземпляра сохраняются сведения, связанные с этим описанием. Они позволяют восстановить визуал из сохранённого состояния при повторном открытии страницы или отчёта.

Легко предположить, как работают эти свойства, но у визуалов часто есть собственная логика обработки сохранённых значений. Поэтому здесь объясняется, какие свойства задаются и как они влияют на создаваемые визуалы Deneb. Это позволяет работать с ними осознанно, без догадок, которые в некоторых случаях приводят к ошибкам.

Простейший случай: визуал Deneb, добавленный вручную

Посмотрим, что происходит при добавлении Deneb на холст отчёта без данных и дополнительных настроек. Базовое определение может выглядеть так:

Визуал добавлен вручную, без дополнительных настроек и данных
{
  "$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/2.4.0/schema.json",
  "name": "2c2722561a0b6c3deded",
  "position": {
    "x": 80,
    "y": 56,
    "z": 0,
    "height": 280,
    "width": 280,
    "tabOrder": 0
  },
  "visual": {
    "visualType": "deneb7E15AEF80B9E4D4F8E12924291ECE89A",
    "objects": {
      "stateManagement": [
        {
          "properties": {
            "viewportHeight": {
              "expr": {
                "Literal": {
                  "Value": "270D"
                }
              }
            },
            "viewportWidth": {
              "expr": {
                "Literal": {
                  "Value": "270D"
                }
              }
            }
          }
        }
      ]
    },
    "drillFilterOtherVisuals": true
  }
}

В разделе visual.objects Deneb сохраняет свою конфигурацию.

Уже присутствует visual.objects.stateManagement. Это внутренние настройки, которые Deneb создаёт при каждом обновлении сведений от Power BI, например при изменении размеров визуала или данных. Они нужны, чтобы при открытии редактора размеры предварительного просмотра соответствовали визуалу в отчёте. Задавать их вручную не нужно: Deneb управляет ими самостоятельно. Подробнее см. в справочнике свойств.

Эквивалентное минимальное определение

Если добавлять собственный визуал через PBIR, следующий пример функционально эквивалентен предыдущему:

Минимальное определение визуала Deneb для PBIR
{
  "$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/2.4.0/schema.json",
  "name": "2c2722561a0b6c3deded",
  "position": {
    "x": 80,
    "y": 56,
    "z": 0,
    "height": 280,
    "width": 280,
    "tabOrder": 0
  },
  "visual": {
    "visualType": "deneb7E15AEF80B9E4D4F8E12924291ECE89A",
    "drillFilterOtherVisuals": true
  }
}

На холсте появится визуал Deneb со стартовой страницей, поскольку активного проекта ещё нет.

Добавление данных в визуал

Теперь добавим данные: столбец Product из таблицы Product и меру $ Sales из таблицы Financials. После добавления полей определение выглядит так:

Определение визуала Deneb с назначенными ролями данных
{
  "$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/2.4.0/schema.json",
  "name": "2c2722561a0b6c3deded",
  "position": {
    /* как в предыдущем примере */
  },
  "visual": {
    "visualType": "deneb7E15AEF80B9E4D4F8E12924291ECE89A",
    "query": {
      "queryState": {
        "dataset": {
          "projections": [
            {
              "field": {
                "Column": {
                  "Expression": {
                    "SourceRef": {
                      "Entity": "Product"
                    }
                  },
                  "Property": "Product"
                }
              },
              "queryRef": "Product.Product",
              "nativeQueryRef": "Product"
            },
            {
              "field": {
                "Measure": {
                  "Expression": {
                    "SourceRef": {
                      "Entity": "Financials"
                    }
                  },
                  "Property": "$ Sales"
                }
              },
              "queryRef": "Financials.$ Sales",
              "nativeQueryRef": "$ Sales"
            }
          ]
        }
      },
      "sortDefinition": {
        "sort": [
          {
            "field": {
              "Column": {
                "Expression": {
                  "SourceRef": {
                    "Entity": "Product"
                  }
                },
                "Property": "Product"
              }
            },
            "direction": "Ascending"
          }
        ],
        "isDefaultSort": true
      }
    },
    "drillFilterOtherVisuals": true
  }
}

Это стандартная структура для любого визуала PBIR. Рассмотрим части, важные для Deneb.

  • visual.query.queryState.dataset представляет столбцы и меры, добавленные в область данных Values. Во внутреннем описании возможностей эта роль называется dataset, что соответствует сопоставлению и назначению данных в спецификации Deneb.
  • Поля dataset создаются и используются под отображаемыми именами из области данных. Если поле не переименовано, имя совпадает с именем столбца или меры в модели. Иначе метаданные поля содержат displayName. Например, после переименования $ Sales в Total Sales в области данных определение будет таким:
{
  "field": {
    "Measure": {
      "Expression": {
        "SourceRef": {
          "Entity": "Financials"
        }
      },
      "Property": "$ Sales"
    }
  },
  "queryRef": "Financials.$ Sales",
  "nativeQueryRef": "$ Sales", // <-- Используется, если имя не изменено в области Values
  "displayName": "Total Sales" // <-- Если задано, Deneb использует это имя при создании набора данных
}

Создание минимальной спецификации

Допустим, у нас есть простая спецификация столбчатой диаграммы Vega-Lite:

Спецификация простой столбчатой диаграммы Vega-Lite
{
  "data": {
    "name": "dataset"
  },
  "mark": {
    "type": "bar"
  },
  "encoding": {
    "y": {
      "field": "Product",
      "type": "nominal"
    },
    "x": {
      "field": "$ Sales",
      "type": "quantitative"
    }
  }
}

Система свойств Power BI требует, чтобы JSON спецификации и конфигурации перед сохранением в свойствах визуала был сериализован в строку с экранированием — например, как при вызове JSON.stringify. Поскольку конфигурация визуала пуста ({}), подготовим свойства так:

Определение визуала Deneb с добавленной спецификацией
{
  "$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/2.4.0/schema.json",
  "name": "2c2722561a0b6c3deded",
  "position": {
    /* как в предыдущем примере */
  },
  "visual": {
    "visualType": "deneb7E15AEF80B9E4D4F8E12924291ECE89A",
    "query": {
      /* как в предыдущем примере */
    },
    "objects": {
      "vega": [
        {
          "properties": {
            "jsonSpec": {
              "expr": {
                "Literal": {
                  "Value": "'{\n  \"data\": {\n    \"name\": \"dataset\"\n  },\n  \"mark\": {\n    \"type\": \"bar\"\n  },\n  \"encoding\": {\n    \"y\": {\n      \"field\": \"Product\",\n      \"type\": \"nominal\"\n    },\n    \"x\": {\n      \"field\": \"$ Sales\",\n      \"type\": \"quantitative\"\n    }\n  }\n}'"
                }
              }
            },
            "jsonConfig": {
              "expr": {
                "Literal": {
                  "Value": "'{}'"
                }
              }
            }
          }
        }
      ]
    },
    "drillFilterOtherVisuals": true
  }
}

Спецификация и конфигурация теперь хранятся в visual.objects.vega, соответственно в свойствах jsonSpec и jsonConfig. При загрузке визуала в Power BI Deneb восстановит и разберёт их, затем отрисует результат. Достаточно, чтобы строка JSON была допустимой; она может содержать комментарии, поскольку Deneb разбирает её как JSONC.

По умолчанию поставщик в Deneb — Vega-Lite, поэтому достаточно задать саму спецификацию. Ниже приведён справочник каждого раздела objects, позволяющий собирать более сложные конфигурации под свои задачи.

Открыв отчёт с этой конфигурацией, мы увидим столбчатую диаграмму:

Столбчатая диаграмма Deneb, созданная через PBIR

Справочник свойств

Ниже описаны объекты objects, используемые Deneb для сохранения конфигурации и состояния. Для каждого свойства по возможности объясняется его назначение и влияние на работу визуала.

objects.vega

Свойства этой группы определяют спецификацию и конфигурацию среды выполнения Vega или Vega-Lite в экземпляре визуала Deneb.

Свойство По умолчанию, если не задано Тип Пояснения
jsonSpec '{}' text Спецификация Vega или Vega-Lite: JSON или JSONC, преобразованный в строку.
jsonConfig '{}' text Объект конфигурации Deneb: JSON или JSONC, преобразованный в строку.
provider 'vegaLite' text (enum) Поставщик для разбора спецификации: vega или vegaLite.
renderMode 'svg' text (enum) Средство отрисовки: canvas или svg.
logLevel 3D (vega.Info) integer Уровень подробности журнала среды выполнения Vega/Vega-Lite: 0 — нет сообщений (None), 1 — ошибки (Error), 2 — предупреждения (Warn), 3 — информация (Info).
enableTooltips true boolean Включает обработчик подсказок Power BI вместо встроенного обработчика Vega. Соответствует флажку Tooltip handler в настройках интерактивности.
enableContextMenu true boolean Определяет, появляется ли контекстное меню Power BI при нажатии правой кнопкой мыши. Соответствует Show context menu on right-click в настройках интерактивности.
enableContextMenuSelector true boolean При включённом меню определяет, пытается ли Deneb сопоставить точку данных для drill-through и других действий, связанных с данными. Соответствует Attempt to resolve data point-specific actions. Имеет значение только при enableContextMenu: true.
enableHighlight false boolean Включает отслеживание событий перекрёстного выделения из других визуалов и реакцию на них. Соответствует Expose cross-highlight values for measures.
enableSelection false boolean Включает отслеживание перекрёстной фильтрации при взаимодействии с визуалом и учёт её состояния. Соответствует Expose cross-filtering values for dataset rows.
selectionMaxDataPoints 50D integer Максимальное число точек данных, объединяемых для операции перекрёстной фильтрации. Имеет значение только при enableSelection: true.
selectionMode simple text (enum) Режим при enableSelection: true. simple отслеживает представление Vega, пытается сопоставить точки данных и применяет перекрёстную фильтрацию. advanced использует расширенную перекрёстную фильтрацию; она работает только при provider: 'vega' и наличии соответствующих событий в спецификации.
version Управляется Deneb text Контрольная запись версии поставщика, с которой визуал отрисовывался в последний раз. Если свойство отсутствует, предполагается текущая включённая в сборку версия Vega или Vega-Lite. Deneb заполняет его автоматически при обновлении визуала и использует для определения необходимых преобразований.

objects.display

Свойства этой группы находятся в меню Rendered visual панели форматирования. Они управляют дополнительной обработкой результата Deneb поверх представления Vega.

Свойство По умолчанию, если не задано Тип Пояснения
scrollbarColor #000000 color Цвет полосы прокрутки контейнера, когда она видна.
scrollbarOpacity 20D integer Непрозрачность полосы прокрутки. Deneb преобразует значение в долю единицы. Допустимые значения: от 0D до 100D.
scrollbarRadius 0D integer Радиус скругления полосы прокрутки в пикселях. Допустимые значения: от 0D до 8D.
scrollbarWidth 10D integer Ширина полосы прокрутки в пикселях. Допустимы значения от 8D: меньшая ширина неудобна для взаимодействия с ползунком.
scrollEventThrottle 5D integer Интервал ограничения частоты обновления позиции прокрутки в миллисекундах в сигнале denebContainer. Допустимые значения: от 0D до 1000D.

objects.dataLimit

Свойства этой группы находятся в меню Data management. Они определяют обработку ограничений числа строк Power BI и настройки непрерывного представления.

Свойство По умолчанию, если не задано Тип Пояснения
override false boolean При true включает Override row limit: Deneb запрашивает дополнительные данные после достижения стандартного предела 10 000 строк.
showCustomVisualNotes true boolean При true показывает раздел Custom visual notes на панели данных редактора во время загрузки данных.
enableIncrementalDataUpdates false boolean При true включает непрерывное представление: обновляет набор данных в существующем представлении Vega вместо повторной компиляции. Работает только для подходящих спецификаций и набора данных в пределах incrementalUpdateThreshold.
incrementalUpdateThreshold 500D integer Максимальное число строк для обновления данных без полной повторной компиляции. Допустимые значения: от 5D до 5000D. Верхний предел 5000D задан Deneb, поскольку основной поток не может безопасно поддерживать обновление большего объёма. Имеет значение только при enableIncrementalDataUpdates: true.

objects.developer

Свойства этой группы предназначены для внутреннего использования.

Свойство По умолчанию, если не задано Тип Пояснения
version Управляется Deneb text Контрольная запись версии визуала, использованной в отчёте в последний раз. Если не задана, предполагается текущая версия из манифеста. Deneb заполняет её автоматически при обновлении визуала, определяет необходимые преобразования при переходе на новую версию и предупреждения при переходе на старую.

objects.stateManagement

Свойства этой группы предназначены для внутреннего использования и сохранения временного состояния между сеансами.

Свойство По умолчанию, если не задано Тип Пояснения
viewportHeight null, управляется Deneb integer Последняя известная высота области отображения визуала в обычном режиме, в пикселях. Если отсутствует, Deneb вычисляет её и обновляет при каждом обновлении визуала по размерам контейнера на холсте. Нужна только для правильного размера предварительного просмотра в расширенном редакторе, не требуется для автоматизации. Приведена для полноты справочника.
viewportWidth null, управляется Deneb integer Последняя известная ширина области отображения визуала в обычном режиме, в пикселях. Если отсутствует, Deneb вычисляет её и обновляет при каждом обновлении визуала по размерам контейнера на холсте. Нужна только для правильного размера предварительного просмотра в расширенном редакторе, не требуется для автоматизации. Приведена для полноты справочника.
denebMetaVersion "", управляется Deneb text Версия внутренней схемы метаданных Deneb на момент последнего сохранения проекта. Нужна для преобразований при открытии проекта в новой версии визуала. Управляется автоматически и не требуется для автоматизации; приведена для полноты справочника.
scaleToZoom false boolean При true разрешение Canvas подстраивается под текущий масштаб отчёта, умноженный на масштаб предварительного просмотра в расширенном редакторе, чтобы уменьшить размытие при масштабе, отличном от 100%. Действует только для Canvas; на SVG не влияет. Подробнее см. панель Settings.
supportFieldConfiguration "" supportFieldConfiguration (text) Сериализованная в JSON карта флагов вспомогательных полей: определяет, создавать ли __highlight, __format, __names и другие поля для каждого столбца или меры. Deneb управляет ею при изменении раздела Supporting Fields: dataset панели Project setup и сохраняет для следующих сеансов.
consolidateFieldParameters false boolean При true Deneb объединяет компоненты параметра полей Power BI в один столбец с массивами значений, названный по имени параметра. Новые проекты получают true. Для проектов до Deneb 2.0 остаётся false, чтобы сохранить совместимость с обходными способами сообщества.

objects.editor

Свойства этой группы находятся в меню Advanced Editor панели форматирования и относятся к работе и оформлению редактора. Они позволяют заранее настроить редактор для пользователей, но не влияют на отрисовку и работу визуала за его пределами.

Свойство По умолчанию, если не задано Тип Пояснения
theme light text (enum) Тема интерфейса редактора: light или dark.
showViewportMarker true boolean При true показывает маркер области отображения в предварительном просмотре.
previewScrollbars true boolean При true показывает полосы прокрутки в предварительном просмотре, если результат отрисовки выходит за границы области контейнера.
backgroundPassthrough true boolean При true фон предварительного просмотра прозрачен: через него видно лежащий ниже фон холста отчёта.
position left text (enum) Расположение панели JSON-редактора: left или right.
fontSize 10D integer Размер шрифта JSON-редактора в пикселях. Допустимые значения: от 8D до 30D.
wordWrap true boolean При true включает перенос строк в JSON-редакторе.
showLineNumbers true boolean При true показывает номера строк в JSON-редакторе.
debouncePeriod 300D integer Интервал отслеживания изменений содержимого JSON-редактора.
debugTableRowsPerPage 50D integer Число строк на странице таблиц данных панели отладки расширенного редактора. Допустимо любое целое значение, но интерфейс предлагает 10, 25, 50, 100, 150 и 200.

Задание свойств

Документация PBIR недостаточно подробно описывает особенности свойств. Следующие сведения о типах помогут работать с ними в Deneb. Здесь рассматривается только поддержка Deneb, а не вся система свойств PBIR.

Распространённые ошибки

  1. Отсутствие суффикса D у числовых значений: Power BI не сможет разобрать их.
  2. Двойное экранирование JSON в jsonSpec: приводит к ошибкам разбора.
  3. Двойные кавычки вместо одинарных для текстовых литералов.
  4. Отсутствие обёртки expr.Literal.Value: свойство не распознаётся.

boolean

Логические свойства используют литералы true или false. Например, свойство со значением true задаётся так:

Структура логического свойства
{
  "enableTooltips": {
    "expr": {
      "Literal": {
        "Value": "true"
      }
    }
  }
}

color

Свойства цвета соответствуют структуре #/definitions/fill в опубликованной Microsoft JSON-схеме тем отчётов. Сейчас Deneb использует и поддерживает только solid.

Цвет можно задать значением Literal в любом известном формате HTML/CSS. Синтаксис немного отличается от обычных текстовых свойств. Цвет заключают в одинарные кавычки, поскольку он хранится как текстовый литерал внутри JSON. Например, красный цвет задаётся так:

Структура свойства цвета со значением Literal
{
  "scrollbarColor": {
    "solid": {
      "color": {
        "expr": {
          "Literal": {
            "Value": "'#FF0000'" // или "'red'", "'rgb(255,0,0)'" и другие форматы
          }
        }
      }
    }
  }
}

Для привязки к теме можно использовать ThemeDataColor:

Структура свойства цвета со значением ThemeDataColor
{
  "scrollbarColor": {
    "solid": {
      "color": {
        "expr": {
          "ThemeDataColor": {
            "ColorId": 1,
            "Percent": 0
          }
        }
      }
    }
  }
}

integer

Целочисленные значения имеют суффикс D, обозначающий числовой литерал. Например, чтобы задать значение 50:

Структура целочисленного свойства
{
  "selectionMaxDataPoints": {
    "expr": {
      "Literal": {
        "Value": "50D"
      }
    }
  }
}

text

Текстовые свойства заключают в одинарные кавычки ('), обозначающие строковый литерал. Например, значение vegaLite задаётся так:

Структура текстового свойства
{
  "provider": {
    "expr": {
      "Literal": {
        "Value": "'vegaLite'"
      }
    }
  }
}

JSON-объекты и массивы, которые нужно хранить как текст, например спецификацию Vega, необходимо преобразовать в строку и экранировать, как показано выше.

supportFieldConfiguration

Свойство supportFieldConfiguration объекта objects.stateManagement хранится как text, но содержит сериализованную в JSON карту флагов вспомогательных полей. Deneb управляет ею при настройке раздела Supporting Fields: dataset панели Project setup. Структура описана для программного создания визуалов и инструментов работы с шаблонами.

В сериализованном JSON:

  • Ключи верхнего уровня — отображаемые имена столбцов и мер в области данных Values.
  • Значения — объекты, описывающие состояние флагов для соответствующего поля.
  • Карта содержит только поля с изменённой конфигурацией: запись добавляется, если настройки отличаются от значений по умолчанию для роли поля. Если записи нет, значения по умолчанию применяются при загрузке. Подробнее см. справочник Supporting Fields.
  • При наличии записи все пять основных флагов — highlight, highlightStatus, highlightComparator, format, formatted — должны явно иметь значение true или false. Флаги параметров names и treatAsParameter необязательны и обычно присутствуют только для полей, помеченных как параметры полей.

Например, чтобы включить вспомогательное поле Format string для столбца [Product] и Highlight value для меры [$ Sales]:

Структура supportFieldConfiguration в visual.json
{
  "supportFieldConfiguration": {
    "expr": {
      "Literal": {
        "Value": "'{\"Product\":{\"highlight\":false,\"highlightStatus\":false,\"highlightComparator\":false,\"format\":true,\"formatted\":false},\"$ Sales\":{\"highlight\":true,\"highlightStatus\":false,\"highlightComparator\":false,\"format\":false,\"formatted\":false}}'"
      }
    }
  }
}

Обратите внимание на внешние одинарные кавычки вокруг строки JSON и экранирование внутренних двойных кавычек. Это стандартный способ PBIR записывать структурированное содержимое в текстовых литералах.