Dodawanie interakcyjności do wizualizacji według wybranych wizualizacji usługi Power BI
Usługa Power BI udostępnia dwa sposoby interakcji z wizualizacjami — wybieranie i filtrowanie. W poniższym przykładzie pokazano, jak wybrać element z jednej wizualizacji i powiadomić inne wizualizacje w raporcie o nowym stanie wyboru.
Interfejs odpowiada Selection
obiektowi:
export interface ISelectionId {
equals(other: ISelectionId): boolean;
includes(other: ISelectionId, ignoreHighlight?: boolean): boolean;
getKey(): string;
getSelector(): Selector;
getSelectorsByColumn(): SelectorsByColumn;
hasIdentity(): boolean;
}
Wybieranie punktów danych za pomocą menedżera wyboru
Obiekt hosta wizualizacji udostępnia metodę tworzenia wystąpienia menedżera wyboru. Menedżer wyboru ma odpowiednią metodę dla każdej z następujących akcji:
- Wybierz pozycję
- Wyczyść zaznaczenie
- Pokaż menu kontekstowe
- Przechowywanie bieżących wyborów
- Sprawdzanie stanu zaznaczenia
Tworzenie wystąpienia menedżera wyboru
Aby użyć menedżera wyboru, utwórz wystąpienie menedżera wyboru. Zazwyczaj wizualizacje tworzą wystąpienie menedżera wyboru w constructor
sekcji obiektu wizualizacji.
export class Visual implements IVisual {
private target: HTMLElement;
private host: IVisualHost;
private selectionManager: ISelectionManager;
// ...
constructor(options: VisualConstructorOptions) {
this.host = options.host;
// ...
this.selectionManager = this.host.createSelectionManager();
}
// ...
}
Tworzenie wystąpienia konstruktora wyboru
Po utworzeniu wystąpienia menedżera wyboru należy utworzyć selections
dla każdego punktu danych wizualizacji. Metoda obiektu createSelectionIdBuilder
hosta wizualizacji generuje wybór dla każdego punktu danych. Ta metoda zwraca wystąpienie obiektu z interfejsem powerbi.visuals.ISelectionIdBuilder
:
export interface ISelectionIdBuilder {
withCategory(categoryColumn: DataViewCategoryColumn, index: number): this;
withSeries(seriesColumn: DataViewValueColumns, valueColumn: DataViewValueColumn | DataViewValueColumnGroup): this;
withMeasure(measureId: string): this;
withMatrixNode(matrixNode: DataViewMatrixNode, levels: DataViewHierarchyLevel[]): this;
withTable(table: DataViewTable, rowIndex: number): this;
createSelectionId(): ISelectionId;
}
Ten obiekt ma odpowiednie metody tworzenia selections
dla różnych typów mapowań widoku danych.
Uwaga
Metody withTable
i withMatrixNode
zostały wprowadzone w interfejsie API 2.5.0 wizualizacji usługi Power BI.
Jeśli musisz użyć opcji dla mapowań widoku danych tabeli lub macierzy, zaktualizuj do interfejsu API w wersji 2.5.0 lub nowszej.
Tworzenie wyborów dla mapowania widoku danych kategorii
Sprawdźmy, w jaki sposób wybory reprezentują mapowanie widoku danych kategorii dla przykładowego modelu semantycznego:
Producent | Type | Wartość |
---|---|---|
Chrysler | Samochód krajowy | 28883 |
Chrysler | Ciężarówka krajowa | 117131 |
Chrysler | Samochód importowy | 0 |
Chrysler | Importowanie ciężarówki | 6362 |
Ford | Samochód krajowy | 50032 |
Ford | Ciężarówka krajowa | 122446 |
Ford | Samochód importowy | 0 |
Ford | Importowanie ciężarówki | 0 |
GM | Samochód krajowy | 65426 |
GM | Ciężarówka krajowa | 138122 |
GM | Samochód importowy | 197 |
GM | Importowanie ciężarówki | 0 |
Honda | Samochód krajowy | 51450 |
Honda | Ciężarówka krajowa | 46115 |
Honda | Samochód importowy | 2932 |
Honda | Importowanie ciężarówki | 0 |
Nissan | Samochód krajowy | 51476 |
Nissan | Ciężarówka krajowa | 47343 |
Nissan | Samochód importowy | 5485 |
Nissan | Importowanie ciężarówki | 1430 |
Toyota | Samochód krajowy | 55643 |
Toyota | Ciężarówka krajowa | 61227 |
Toyota | Samochód importowy | 20799 |
Toyota | Importowanie ciężarówki | 23614 |
Wizualizacja używa następującego mapowania widoku danych:
{
"dataRoles": [
{
"displayName": "Columns",
"name": "columns",
"kind": "Grouping"
},
{
"displayName": "Rows",
"name": "rows",
"kind": "Grouping"
},
{
"displayName": "Values",
"name": "values",
"kind": "Measure"
}
],
"dataViewMappings": [
{
"categorical": {
"categories": {
"for": {
"in": "columns"
}
},
"values": {
"group": {
"by": "rows",
"select": [
{
"for": {
"in": "values"
}
}
]
}
}
}
}
]
}
W poprzednim przykładzie Manufacturer
parametr ma wartość columns
i Type
ma wartość rows
. Seria jest tworzona przez grupowanie wartości według rows
(Type
).
Wizualizacja powinna mieć możliwość fragmentowania danych według Manufacturer
lub Type
.
Jeśli na przykład użytkownik wybierze Chrysler
wartość Manufacturer
, inne wizualizacje powinny wyświetlić następujące dane:
Producent | Type | Wartość |
---|---|---|
Chrysler | Samochód krajowy | 28883 |
Chrysler | Ciężarówka krajowa | 117131 |
Chrysler | Samochód importowy | 0 |
Chrysler | Importowanie ciężarówki | 6362 |
Gdy użytkownik wybierze Import Car
pozycję Type
(wybiera dane według serii), inne wizualizacje powinny wyświetlać następujące dane:
Producent | Type | Wartość |
---|---|---|
Chrysler | Samochód importowy | 0 |
Ford | Samochód importowy | 0 |
GM | Samochód importowy | 197 |
Honda | Samochód importowy | 2932 |
Nissan | Samochód importowy | 5485 |
Toyota | Samochód importowy | 20799 |
Aby wyświetlić wycinek danych, wypełnij koszyki danych wizualizacji w następujący sposób:
W poprzednim przykładzie Manufacturer
jest kategoria (kolumny), Type
jest serią (wierszami) i Sales
jest Values
dla serii.
Uwaga
Values
są wymagane do wyświetlania serii, ponieważ zgodnie z mapowaniem Values
widoku danych są grupowane według Rows
danych.
Tworzenie wyborów dla kategorii
// categories
const categories = dataView.categorical.categories;
// create label for 'Manufacturer' column
const p = document.createElement("p") as HTMLParagraphElement;
p.innerText = categories[0].source.displayName.toString();
this.target.appendChild(p);
// get count of category elements
const categoriesCount = categories[0].values.length;
// iterate all categories to generate selection and create button elements to use selections
for (let categoryIndex = 0; categoryIndex < categoriesCount; categoryIndex++) {
const categoryValue: powerbi.PrimitiveValue = categories[0].values[categoryIndex];
const categorySelectionId = this.host.createSelectionIdBuilder()
.withCategory(categories[0], categoryIndex) // we have only one category (only one `Manufacturer` column)
.createSelectionId();
this.dataPoints.push({
value: categoryValue,
selection: categorySelectionId
});
console.log(categorySelectionId);
// create button element to apply selection on click
const button = document.createElement("button") as HTMLButtonElement;
button.value = categoryValue.toString();
button.innerText = categoryValue.toString();
button.addEventListener("click", () => {
// handle click event to apply correspond selection
this.selectionManager.select(categorySelectionId);
});
this.target.appendChild(button);
}
W poprzednim przykładowym kodzie iterujemy wszystkie kategorie. W każdej iteracji wywołujemy createSelectionIdBuilder
metodę tworzenia kolejnego wyboru dla każdej kategorii przez wywołanie withCategory
metody konstruktora wyboru. Metoda createSelectionId
jest używana jako ostateczna metoda, aby zwrócić wygenerowany selection
obiekt.
W metodzie withCategory
przekazujemy kolumnę category
, w przykładzie , jej Manufacturer
i indeks elementu category.
Tworzenie wyborów dla serii
// get groupped values for series
const series: powerbi.DataViewValueColumnGroup[] = dataView.categorical.values.grouped();
// create label for 'Type' column
const p2 = document.createElement("p") as HTMLParagraphElement;
p2.innerText = dataView.categorical.values.source.displayName;
this.target.appendChild(p2);
// iterate all series to generate selection and create button elements to use selections
series.forEach( (ser: powerbi.DataViewValueColumnGroup) => {
// create selection id for series
const seriesSelectionId = this.host.createSelectionIdBuilder()
.withSeries(dataView.categorical.values, ser)
.createSelectionId();
this.dataPoints.push({
value: ser.name,
selection: seriesSelectionId
});
// create button element to apply selection on click
const button = document.createElement("button") as HTMLButtonElement;
button.value =ser.name.toString();
button.innerText = ser.name.toString();
button.addEventListener("click", () => {
// handle click event to apply correspond selection
this.selectionManager.select(seriesSelectionId);
});
this.target.appendChild(button);
});
Tworzenie wyborów dla mapowania widoku danych tabeli
W poniższym przykładzie przedstawiono mapowanie widoku danych tabeli:
{
"dataRoles": [
{
"displayName": "Values",
"name": "values",
"kind": "GroupingOrMeasure"
}
],
"dataViewMappings": [
{
"table": {
"rows": {
"for": {
"in": "values"
}
}
}
}
]
}
Aby utworzyć wybór dla każdego wiersza mapowania widoku danych tabeli, wywołaj metodę withTable
konstruktora wyboru.
public update(options: VisualUpdateOptions) {
const dataView = options.dataViews[0];
dataView.table.rows.forEach((row: DataViewTableRow, rowIndex: number) => {
this.target.appendChild(rowDiv);
const selection: ISelectionId = this.host.createSelectionIdBuilder()
.withTable(dataView.table, rowIndex)
.createSelectionId();
}
}
Kod wizualizacji iteruje wiersze tabeli, a każdy wiersz wywołuje metodę withTable
tabeli. withTable
Parametry metody to table
obiekt i indeks wiersza tabeli.
Tworzenie wyborów dla mapowania widoku danych macierzy
public update(options: VisualUpdateOptions) {
const host = this.host;
const rowLevels: powerbi.DataViewHierarchyLevel[] = dataView.matrix.rows.levels;
const columnLevels: powerbi.DataViewHierarchyLevel[] = dataView.matrix.rows.levels;
// iterate rows hierarchy
nodeWalker(dataView.matrix.rows.root, rowLevels);
// iterate columns hierarchy
nodeWalker(dataView.matrix.columns.root, columnLevels);
function nodeWalker(node: powerbi.DataViewMatrixNode, levels: powerbi.DataViewHierarchyLevel[]) {
const nodeSelection = host.createSelectionIdBuilder().withMatrixNode(node, levels);
if (node.children && node.children.length) {
node.children.forEach(child => {
nodeWalker(child, levels);
});
}
}
}
W przykładzie nodeWalker
cyklicznie wywołuje każdy węzeł i węzeł podrzędny.
nodeWalker
tworzy nodeSelection
obiekt w każdym wywołaniu. Każda z nich nodeSelection
reprezentuje selection
odpowiednie węzły.
Wybieranie punktów danych w celu wycinka innych wizualizacji
W tym przykładzie utworzyliśmy procedurę obsługi kliknięć dla elementów przycisku. Procedura obsługi wywołuje metodę select
menedżera wyboru i przekazuje obiekt zaznaczenia.
button.addEventListener("click", () => {
// handle click event to apply correspond selection
this.selectionManager.select(categorySelectionId);
});
Interfejs select
metody:
interface ISelectionManager {
// ...
select(selectionId: ISelectionId | ISelectionId[], multiSelect?: boolean): IPromise<ISelectionId[]>;
// ...
}
Metoda select
może akceptować tablicę wyborów. Dzięki temu wizualizacja może jednocześnie wybrać kilka punktów danych. Drugi parametr , multiSelect
jest odpowiedzialny za wybór wielokrotny. Jeśli multiSelect
wartość ma wartość true, usługa Power BI nie wyczyści poprzedniego stanu zaznaczenia, gdy zastosuje bieżące zaznaczenie. Jeśli wartość ma wartość false, poprzednie zaznaczenie zostanie zastąpione.
Typowym przykładem użycia multiSelect
jest obsługa stanu przycisku Ctrl na zdarzeniu kliknięcia. Po naciśnięciu Ctrl w dół można wybrać więcej niż jeden obiekt.
button.addEventListener("click", (mouseEvent) => {
const multiSelect = (mouseEvent as MouseEvent).ctrlKey;
this.selectionManager.select(seriesSelectionId, multiSelect);
});