Общие сведения о сопоставлении представлений данных в визуальных элементах Power BI
В этой статье описывается сопоставление представлений данных и описывается использование ролей данных для создания различных типов визуальных элементов. В нем объясняется, как указать условные требования для ролей данных и различных dataMappings
типов.
Каждое допустимое сопоставление создает представление данных. В определенных условиях можно предоставить несколько сопоставлений данных. Поддерживаемые варианты сопоставления:
"dataViewMappings": [
{
"conditions": [ ... ],
"categorical": { ... },
"single": { ... },
"table": { ... },
"matrix": { ... }
}
]
Power BI создает сопоставление с представлением данных, только если допустимое сопоставление также определено в dataViewMappings
.
Другими словами, categorical
может быть определено в dataViewMappings
других сопоставлениях, например table
или single
не может быть. В этом случае Power BI создает представление данных с одним categorical
сопоставлением, а table
другие сопоставления остаются неопределенными. Например:
"dataViewMappings": [
{
"categorical": {
"categories": [ ... ],
"values": [ ... ]
},
"metadata": { ... }
}
]
Условия
В conditions
этом разделе устанавливаются правила для конкретного сопоставления данных. Если данные соответствуют одному из описанных наборов условий, визуальный элемент принимает данные как допустимые.
Для каждого поля можно указать минимальное и максимальное значение. Значение представляет количество полей, которые могут быть привязаны к этой роли данных.
Примечание.
Если роль данных опущена в условии, она может иметь любое количество полей.
В следующем примере category
ограничение ограничено одним полем данных и measure
ограничено двумя полями данных.
"conditions": [
{ "category": { "max": 1 }, "measure": { "max": 2 } },
]
Можно также задать несколько условий для роли данных. В этом случае данные допустимы, если выполняется одно из условий.
"conditions": [
{ "category": { "min": 1, "max": 1 }, "measure": { "min": 2, "max": 2 } },
{ "category": { "min": 2, "max": 2 }, "measure": { "min": 1, "max": 1 } }
]
В предыдущем примере требуется одно из следующих двух условий:
- Ровно одно поле категории и ровно две меры
- Ровно две категории и ровно одна мера
Сопоставление отдельных данных
Сопоставление отдельных данных — это простейшая форма сопоставления данных. Он принимает одно поле меры и возвращает общее значение. Если поле является числовым, возвращается сумма. В противном случае возвращается количество уникальных значений.
Чтобы использовать сопоставление отдельных данных, определите имя роли данных, которую требуется сопоставить. Это сопоставление работает только с одним полем меры. Если назначено второе поле, представление данных не создается, поэтому рекомендуется включить условие, ограничивающее данные одним полем.
Примечание.
Это сопоставление данных нельзя использовать в сочетании с любым другим сопоставлением данных. Оно предназначено для уменьшения числа данных до одного числового значения.
Например:
{
"dataRoles": [
{
"displayName": "Y",
"name": "Y",
"kind": "Measure"
}
],
"dataViewMappings": [
{
"conditions": [
{
"Y": {
"max": 1
}
}
],
"single": {
"role": "Y"
}
}
]
}
Полученное представление данных по-прежнему может содержать другие типы сопоставления, такие как таблица или категориальная, но каждое сопоставление содержит только одно значение. Рекомендуется получить доступ к значению только в одном сопоставлении.
{
"dataView": [
{
"metadata": null,
"categorical": null,
"matrix": null,
"table": null,
"tree": null,
"single": {
"value": 94163140.3560001
}
}
]
}
Следующий пример кода обрабатывает сопоставление простых представлений данных:
"use strict";
import powerbi from "powerbi-visuals-api";
import DataView = powerbi.DataView;
import DataViewSingle = powerbi.DataViewSingle;
// standard imports
// ...
export class Visual implements IVisual {
private target: HTMLElement;
private host: IVisualHost;
private valueText: HTMLParagraphElement;
constructor(options: VisualConstructorOptions) {
// constructor body
this.target = options.element;
this.host = options.host;
this.valueText = document.createElement("p");
this.target.appendChild(this.valueText);
// ...
}
public update(options: VisualUpdateOptions) {
const dataView: DataView = options.dataViews[0];
const singleDataView: DataViewSingle = dataView.single;
if (!singleDataView ||
!singleDataView.value ) {
return
}
this.valueText.innerText = singleDataView.value.toString();
}
}
Предыдущий пример кода приводит к отображению одного значения из Power BI:
Сопоставление категориальных данных
Сопоставление категориальных данных используется для получения независимых групп или категорий данных. Категории также можно сгруппировать с помощью "группировать по" в сопоставлении данных.
Базовое сопоставление категориальных данных
Рассмотрим следующие роли и сопоставления данных:
"dataRoles":[
{
"displayName": "Category",
"name": "category",
"kind": "Grouping"
},
{
"displayName": "Y Axis",
"name": "measure",
"kind": "Measure"
}
],
"dataViewMappings": {
"categorical": {
"categories": {
"for": { "in": "category" }
},
"values": {
"select": [
{ "bind": { "to": "measure" } }
]
}
}
}
В предыдущем примере считывается сообщение "Сопоставление роли category
данных таким образом, чтобы для каждого поля, в которое я перетаскивалась category
, сопоставляется categorical.categories
его данные с . Кроме того, сопоставить роль данных measure
с categorical.values
."
- для... in: включает все элементы этой роли данных в запросе данных.
- связывать... to: Создает тот же результат, что и для... но ожидает, что роль данных будет иметь условие, ограничивающее его одним полем.
Группирование категориальных данных
В следующем примере используются те же две роли данных, что и предыдущий пример, и добавляется еще две роли данных с именем grouping
и measure2
.
"dataRoles":[
{
"displayName": "Category",
"name": "category",
"kind": "Grouping"
},
{
"displayName": "Y Axis",
"name": "measure",
"kind": "Measure"
},
{
"displayName": "Grouping with",
"name": "grouping",
"kind": "Grouping"
},
{
"displayName": "X Axis",
"name": "measure2",
"kind": "Grouping"
}
],
"dataViewMappings": [
{
"categorical": {
"categories": {
"for": {
"in": "category"
}
},
"values": {
"group": {
"by": "grouping",
"select": [{
"bind": {
"to": "measure"
}
},
{
"bind": {
"to": "measure2"
}
}
]
}
}
}
}
]
Разница между этим сопоставлением и базовым сопоставлением заключается categorical.values
в сопоставлении. При сопоставлении measure
ролей и measure2
ролей данных с ролью grouping
данных можно масштабировать ось x и y соответствующим образом.
Группировать иерархические данные
В следующем примере категориальные данные используются для создания иерархии, которая может использоваться для поддержки действий детализации .
В следующем примере показаны роли и сопоставления данных:
"dataRoles": [
{
"displayName": "Categories",
"name": "category",
"kind": "Grouping"
},
{
"displayName": "Measures",
"name": "measure",
"kind": "Measure"
},
{
"displayName": "Series",
"name": "series",
"kind": "Measure"
}
],
"dataViewMappings": [
{
"categorical": {
"categories": {
"for": {
"in": "category"
}
},
"values": {
"group": {
"by": "series",
"select": [{
"for": {
"in": "measure"
}
}
]
}
}
}
}
]
Рассмотрим следующие категориальные данные:
Страна или регион | 2013 | 2014 | 2015 | 2016 |
---|---|---|---|---|
USA | x | x | 650 | 350 |
Канада | x | 630 | 490 | x |
Мексика | 645 | x | x | x |
UK | x | x | 831 | x |
Power BI создает категориальное представление данных со следующим набором категорий.
{
"categorical": {
"categories": [
{
"source": {...},
"values": [
"Canada",
"USA",
"UK",
"Mexico"
],
"identity": [...],
"identityFields": [...],
}
]
}
}
Каждая category
из них сопоставляется с набором values
. Каждая из них values
сгруппирована series
по , которая выражается в виде лет.
Например, каждый values
массив представляет один год.
Кроме того, каждый values
массив имеет четыре значения: Канада, США, Великобритания и Мексика.
{
"values": [
// Values for year 2013
{
"source": {...},
"values": [
null, // Value for `Canada` category
null, // Value for `USA` category
null, // Value for `UK` category
645 // Value for `Mexico` category
],
"identity": [...],
},
// Values for year 2014
{
"source": {...},
"values": [
630, // Value for `Canada` category
null, // Value for `USA` category
null, // Value for `UK` category
null // Value for `Mexico` category
],
"identity": [...],
},
// Values for year 2015
{
"source": {...},
"values": [
490, // Value for `Canada` category
650, // Value for `USA` category
831, // Value for `UK` category
null // Value for `Mexico` category
],
"identity": [...],
},
// Values for year 2016
{
"source": {...},
"values": [
null, // Value for `Canada` category
350, // Value for `USA` category
null, // Value for `UK` category
null // Value for `Mexico` category
],
"identity": [...],
}
]
}
Следующий пример кода предназначен для обработки сопоставления категориального представления данных. В этом примере создается иерархическая структура Country /Region > Year > Value.
"use strict";
import powerbi from "powerbi-visuals-api";
import DataView = powerbi.DataView;
import DataViewCategorical = powerbi.DataViewCategorical;
import DataViewValueColumnGroup = powerbi.DataViewValueColumnGroup;
import PrimitiveValue = powerbi.PrimitiveValue;
// standard imports
// ...
export class Visual implements IVisual {
private target: HTMLElement;
private host: IVisualHost;
private categories: HTMLElement;
constructor(options: VisualConstructorOptions) {
// constructor body
this.target = options.element;
this.host = options.host;
this.categories = document.createElement("pre");
this.target.appendChild(this.categories);
// ...
}
public update(options: VisualUpdateOptions) {
const dataView: DataView = options.dataViews[0];
const categoricalDataView: DataViewCategorical = dataView.categorical;
if (!categoricalDataView ||
!categoricalDataView.categories ||
!categoricalDataView.categories[0] ||
!categoricalDataView.values) {
return;
}
// Categories have only one column in data buckets
// To support several columns of categories data bucket, iterate categoricalDataView.categories array.
const categoryFieldIndex = 0;
// Measure has only one column in data buckets.
// To support several columns on data bucket, iterate years.values array in map function
const measureFieldIndex = 0;
let categories: PrimitiveValue[] = categoricalDataView.categories[categoryFieldIndex].values;
let values: DataViewValueColumnGroup[] = categoricalDataView.values.grouped();
let data = {};
// iterate categories/countries-regions
categories.map((category: PrimitiveValue, categoryIndex: number) => {
data[category.toString()] = {};
// iterate series/years
values.map((years: DataViewValueColumnGroup) => {
if (!data[category.toString()][years.name] && years.values[measureFieldIndex].values[categoryIndex]) {
data[category.toString()][years.name] = []
}
if (years.values[0].values[categoryIndex]) {
data[category.toString()][years.name].push(years.values[measureFieldIndex].values[categoryIndex]);
}
});
});
this.categories.innerText = JSON.stringify(data, null, 6);
console.log(data);
}
}
Ниже приведен результирующий визуальный элемент:
Таблицы сопоставления
Представление данных таблицы — это, по сути, список точек данных, в которых можно агрегировать числовые точки данных.
Например, используйте те же данные в предыдущем разделе, но со следующими возможностями:
"dataRoles": [
{
"displayName": "Column",
"name": "column",
"kind": "Grouping"
},
{
"displayName": "Value",
"name": "value",
"kind": "Measure"
}
],
"dataViewMappings": [
{
"table": {
"rows": {
"select": [
{
"for": {
"in": "column"
}
},
{
"for": {
"in": "value"
}
}
]
}
}
}
]
Визуализировать представление данных таблицы, как показано в следующем примере:
Страна или регион | Год | Продажи |
---|---|---|
USA | 2016 | 100 |
USA | 2015 | 50 |
Канада | 2015 | 200 |
Канада | 2015 | 50 |
Мексика | 2013 | 300 |
UK | 2014 | 150 |
USA | 2015 | 75 |
Привязка данных:
Power BI отображает данные в виде представления данных таблицы. Не предполагайте, что данные упорядочены.
{
"table" : {
"columns": [...],
"rows": [
[
"Canada",
2014,
630
],
[
"Canada",
2015,
490
],
[
"Mexico",
2013,
645
],
[
"UK",
2014,
831
],
[
"USA",
2015,
650
],
[
"USA",
2016,
350
]
]
}
}
Чтобы агрегировать данные, выберите нужное поле и выберите "Сумма".
Пример кода для обработки сопоставления представления данных таблицы.
"use strict";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
// ...
import DataViewMetadataColumn = powerbi.DataViewMetadataColumn;
import DataViewTable = powerbi.DataViewTable;
import DataViewTableRow = powerbi.DataViewTableRow;
import PrimitiveValue = powerbi.PrimitiveValue;
// standard imports
// ...
export class Visual implements IVisual {
private target: HTMLElement;
private host: IVisualHost;
private table: HTMLParagraphElement;
constructor(options: VisualConstructorOptions) {
// constructor body
this.target = options.element;
this.host = options.host;
this.table = document.createElement("table");
this.target.appendChild(this.table);
// ...
}
public update(options: VisualUpdateOptions) {
const dataView: DataView = options.dataViews[0];
const tableDataView: DataViewTable = dataView.table;
if (!tableDataView) {
return
}
while(this.table.firstChild) {
this.table.removeChild(this.table.firstChild);
}
//draw header
const tableHeader = document.createElement("th");
tableDataView.columns.forEach((column: DataViewMetadataColumn) => {
const tableHeaderColumn = document.createElement("td");
tableHeaderColumn.innerText = column.displayName
tableHeader.appendChild(tableHeaderColumn);
});
this.table.appendChild(tableHeader);
//draw rows
tableDataView.rows.forEach((row: DataViewTableRow) => {
const tableRow = document.createElement("tr");
row.forEach((columnValue: PrimitiveValue) => {
const cell = document.createElement("td");
cell.innerText = columnValue.toString();
tableRow.appendChild(cell);
})
this.table.appendChild(tableRow);
});
}
}
Файл style/visual.less
стилей визуальных элементов содержит макет таблицы:
table {
display: flex;
flex-direction: column;
}
tr, th {
display: flex;
flex: 1;
}
td {
flex: 1;
border: 1px solid black;
}
Полученный визуальный элемент выглядит следующим образом:
Сопоставление данных матрицы
Сопоставление данных матрицы аналогично сопоставлению данных таблиц, но строки представлены иерархически. Любое из значений роли данных можно использовать в качестве значения заголовка столбца.
{
"dataRoles": [
{
"name": "Category",
"displayName": "Category",
"displayNameKey": "Visual_Category",
"kind": "Grouping"
},
{
"name": "Column",
"displayName": "Column",
"displayNameKey": "Visual_Column",
"kind": "Grouping"
},
{
"name": "Measure",
"displayName": "Measure",
"displayNameKey": "Visual_Values",
"kind": "Measure"
}
],
"dataViewMappings": [
{
"matrix": {
"rows": {
"for": {
"in": "Category"
}
},
"columns": {
"for": {
"in": "Column"
}
},
"values": {
"select": [
{
"for": {
"in": "Measure"
}
}
]
}
}
}
]
}
Иерархическая структура данных матрицы
Power BI создает иерархическую структуру данных. Корень иерархии дерева содержит данные из столбца Category
"Родители" роли данных с дочерними элементами из столбца "Дочерние" таблицы ролей данных.
Семантическая модель:
Родители | Children | Внучата | Столбцы | Значения |
---|---|---|---|---|
Parent1 | Child1 | Grand child1 | Col1 | 5 |
Parent1 | Child1 | Grand child1 | Col2 | 6 |
Parent1 | Child1 | Grand child2 | Col1 | 7 |
Parent1 | Child1 | Grand child2 | Col2 | 8 |
Parent1 | Child2 | Grand child3 | Col1 | 5 |
Parent1 | Child2 | Grand child3 | Col2 | 3 |
Parent1 | Child2 | Grand child4 | Col1 | 4 |
Parent1 | Child2 | Grand child4 | Col2 | 9 |
Parent1 | Child2 | Grand child5 | Col1 | 3 |
Parent1 | Child2 | Grand child5 | Col2 | 5 |
Parent2 | Child3 | Grand child6 | Col1 | 1 |
Parent2 | Child3 | Grand child6 | Col2 | 2 |
Parent2 | Child3 | Grand child7 | Col1 | 7 |
Parent2 | Child3 | Grand child7 | Col2 | 1 |
Parent2 | Child3 | Grand child8 | Col1 | 10 |
Parent2 | Child3 | Grand child8 | Col2 | 13 |
Основной визуальный элемент матрицы Power BI отображает данные в виде таблицы.
Визуальный элемент получает свою структуру данных, как описано в следующем коде (здесь показаны только первые две строки таблицы):
{
"metadata": {...},
"matrix": {
"rows": {
"levels": [...],
"root": {
"childIdentityFields": [...],
"children": [
{
"level": 0,
"levelValues": [...],
"value": "Parent1",
"identity": {...},
"childIdentityFields": [...],
"children": [
{
"level": 1,
"levelValues": [...],
"value": "Child1",
"identity": {...},
"childIdentityFields": [...],
"children": [
{
"level": 2,
"levelValues": [...],
"value": "Grand child1",
"identity": {...},
"values": {
"0": {
"value": 5 // value for Col1
},
"1": {
"value": 6 // value for Col2
}
}
},
...
]
},
...
]
},
...
]
}
},
"columns": {
"levels": [...],
"root": {
"childIdentityFields": [...],
"children": [
{
"level": 0,
"levelValues": [...],
"value": "Col1",
"identity": {...}
},
{
"level": 0,
"levelValues": [...],
"value": "Col2",
"identity": {...}
},
...
]
}
},
"valueSources": [...]
}
}
Развертывание и свертывание заголовков строк
Для API 4.1.0 или более поздней версии данные матрицы поддерживают расширение и удаление заголовков строк. Из API 4.2 можно развернуть и свернуть весь уровень программным способом. Функция развертывания и свертывание оптимизирует получение данных в dataView, позволяя пользователю развернуть или свернуть строку без получения всех данных для следующего уровня. Он получает только данные для выбранной строки. Состояние расширения заголовка строки остается согласованным между закладками и даже в сохраненных отчетах. Это не зависит от каждого визуального элемента.
Команды развернуть и свернуть можно добавить в контекстное меню, указав dataRoles
параметр методу showContextMenu
.
Чтобы развернуть большое количество точек данных, используйте API получения дополнительных данных с помощью API развертывания и свершения.
Функции API
Следующие элементы были добавлены в API версии 4.1.0, чтобы включить расширение и удаление заголовков строк:
Флаг
isCollapsed
в :DataViewTreeNode
interface DataViewTreeNode { //... /** * TRUE if the node is Collapsed * FALSE if it is Expanded * Undefined if it cannot be Expanded (e.g. subtotal) */ isCollapsed?: boolean; }
Метод
toggleExpandCollapse
в интерфейсеISelectionManger
:interface ISelectionManager { //... showContextMenu(selectionId: ISelectionId, position: IPoint, dataRoles?: string): IPromise<{}>; // dataRoles is the name of the role of the selected data point toggleExpandCollapse(selectionId: ISelectionId, entireLevel?: boolean): IPromise<{}>; // Expand/Collapse an entire level will be available from API 4.2.0 //... }
Флаг
canBeExpanded
в DataViewHierarchyLevel:interface DataViewHierarchyLevel { //... /** If TRUE, this level can be expanded/collapsed */ canBeExpanded?: boolean; }
Визуальные требования
Чтобы включить функцию свертывание развертывания в визуальном элементе с помощью представления данных матрицы:
Добавьте следующий код в файл capabilities.json:
"expandCollapse": { "roles": ["Rows"], //”Rows” is the name of rows data role "addDataViewFlags": { "defaultValue": true //indicates if the DataViewTreeNode will get the isCollapsed flag by default } },
Убедитесь, что роли можно детализации:
"drilldown": { "roles": ["Rows"] },
Для каждого узла создайте экземпляр построителя выбора, вызвав
withMatrixNode
метод на выбранном уровне иерархии узлов и создав .selectionId
Например:let nodeSelectionBuilder: ISelectionIdBuilder = visualHost.createSelectionIdBuilder(); // parantNodes is a list of the parents of the selected node. // node is the current node which the selectionId is created for. parentNodes.push(node); for (let i = 0; i < parentNodes.length; i++) { nodeSelectionBuilder = nodeSelectionBuilder.withMatrixNode(parentNodes[i], levels); } const nodeSelectionId: ISelectionId = nodeSelectionBuilder.createSelectionId();
Создайте экземпляр диспетчера выбора и используйте
selectionManager.toggleExpandCollapse()
метод с параметром объекта, созданного для выбранногоselectionId
узла. Рассмотрим пример.// handle click events to apply expand\collapse action for the selected node button.addEventListener("click", () => { this.selectionManager.toggleExpandCollapse(nodeSelectionId); });
Примечание.
- Если выбранный узел не является узлом строки, PowerBI будет игнорировать вызовы развертывания и свертывание, а команды развертывания и свертывание будут удалены из контекстного меню.
- Параметр
dataRoles
требуется дляshowContextMenu
метода только в том случае, если визуальный элемент поддерживаетdrilldown
илиexpandCollapse
функции. Если визуальный элемент поддерживает эти функции, но dataRoles не был предоставлен, ошибка выводится в консоль при использовании визуального элемента разработчика или при отладке общедоступного визуального элемента с включенным режимом отладки.
Рекомендации и ограничения
- После развертывания узла новые ограничения данных будут применены к DataView. Новый DataView может не включать некоторые узлы, представленные в предыдущем dataView.
- При использовании развернуть или свернуть итоги добавляются, даже если визуальный элемент не запрашивал их.
- Расширение и удаление столбцов не поддерживается.
Сохранение всех столбцов метаданных
Для API 5.1.0 или более поздней версии поддерживается сохранение всех столбцов метаданных. Эта функция позволяет визуальному элементу получать метаданные для всех столбцов независимо от того, какие их активные проекции.
Добавьте следующие строки в файл capabilities.json :
"keepAllMetadataColumns": {
"type": "boolean",
"description": "Indicates that visual is going to receive all metadata columns, no matter what the active projections are"
}
Задание этого свойства приведет к получению true
всех метаданных, включая свернутые столбцы. Установка или выход из неопределенного приведет к получению false
метаданных только для столбцов с активными проекциями (например, развернутыми).
Алгоритм сокращения данных
Алгоритм уменьшения данных определяет, какие данные и сколько данных получено в представлении данных.
Для счетчика задано максимальное количество значений, которые может принимать представление данных. Если имеется больше значений , алгоритм сокращения данных определяет, какие значения должны быть получены.
Типы алгоритмов сокращения данных
Существует четыре типа параметров алгоритма сокращения данных:
top
: первые значения счетчика взяты из семантической модели.bottom
: последние значения счетчика взяты из семантической модели.sample
: включены первые и последние элементы и количество элементов с равными интервалами между ними. Например, если у вас есть семантическая модель [0, 1, 2, ... 100] и число 9, вы получаете значения [0, 10, 20 ... 100].window
: загружает одно окно точек данных за раз, содержащее элементы счетчика.top
В настоящее время иwindow
эквивалентны. В будущем параметр окна будет полностью поддерживаться.
По умолчанию все визуальные элементы Power BI имеют лучший алгоритм уменьшения данных, применяемый с набором счетчиков в 1000 точек данных. Это значение по умолчанию эквивалентно настройке следующих свойств в файле capabilities.json :
"dataReductionAlgorithm": {
"top": {
"count": 1000
}
}
Значение счетчика можно изменить на любое целочисленное значение до 30000. Визуальные элементы Power BI на основе R могут поддерживать до 150000 строк.
Использование алгоритма сокращения данных
Алгоритм сокращения данных можно использовать в сопоставлении категориальных, табличных или матрицных представлений данных.
В категориальное сопоставление данных можно добавить алгоритм в раздел values
"категории" и /или "групп" для сопоставления категориальных данных.
"dataViewMappings": {
"categorical": {
"categories": {
"for": { "in": "category" },
"dataReductionAlgorithm": {
"window": {
"count": 300
}
}
},
"values": {
"group": {
"by": "series",
"select": [{
"for": {
"in": "measure"
}
}
],
"dataReductionAlgorithm": {
"top": {
"count": 100
}
}
}
}
}
}
В сопоставлении представлений данных таблицы примените алгоритм уменьшения данных к rows
разделу таблицы сопоставления представления данных.
"dataViewMappings": [
{
"table": {
"rows": {
"for": {
"in": "values"
},
"dataReductionAlgorithm": {
"top": {
"count": 2000
}
}
}
}
}
]
Алгоритм уменьшения данных можно применить к rows
матрице сопоставления представления данных и columns
разделам.