Aggiungere interattività agli oggetti visivi in base alle selezioni degli oggetti visivi di Power BI

Power BI offre due modi per interagire con gli oggetti visivi, ovvero la selezione e il filtro. Nell'esempio seguente viene illustrato come selezionare un elemento da un oggetto visivo e notificare agli altri oggetti visivi nel report lo stato di nuova selezione.

L'interfaccia corrisponde a un Selection oggetto :

export interface ISelectionId {
    equals(other: ISelectionId): boolean;
    includes(other: ISelectionId, ignoreHighlight?: boolean): boolean;
    getKey(): string;
    getSelector(): Selector;
    getSelectorsByColumn(): SelectorsByColumn;
    hasIdentity(): boolean;
}

Usare gestione selezione per selezionare i punti dati

L'oggetto host visivo fornisce un metodo per la creazione di un'istanza del gestore di selezione. Il gestore di selezione dispone di un metodo corrispondente per ognuna delle azioni seguenti:

  • Seleziona
  • Deselezionare la selezione
  • Mostra il menu di scelta rapida
  • Archiviare le selezioni correnti
  • Controllare lo stato di selezione

Creare un'istanza del gestore di selezione

Per usare gestione selezione, creare l'istanza di un gestore di selezione. In genere, gli oggetti visivi creano un'istanza di Gestione selezione nella constructor sezione dell'oggetto visivo.

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();
    }
    // ...
}

Creare un'istanza del generatore di selezione

Quando viene creata l'istanza di Gestione selezione, è necessario creare selections per ogni punto dati dell'oggetto visivo. Il metodo dell'oggetto createSelectionIdBuilder host visivo genera una selezione per ogni punto dati. Questo metodo restituisce un'istanza dell'oggetto con interfaccia 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;
}

Questo oggetto dispone di metodi corrispondenti da creare selections per diversi tipi di mapping delle viste dati.

Nota

I metodi withTable e withMatrixNode sono stati introdotti nell'API 2.5.0 degli oggetti visivi di Power BI. Se è necessario usare le selezioni per i mapping di vista dati tabella o matrice, eseguire l'aggiornamento all'API versione 2.5.0 o successiva.

Creare selezioni per il mapping di visualizzazione dati categorica

Si esaminerà ora come le selezioni rappresentano il mapping delle visualizzazioni dati categoriche per un modello semantico di esempio:

Produttore Tipo valore
Chrysler Auto domestica 28883
Chrysler Camion domestico 117131
Chrysler Importa auto 0
Chrysler Importa camion 6362
Ford Auto domestica 50032
Ford Camion domestico 122446
Ford Importa auto 0
Ford Importa camion 0
GM Auto domestica 65426
GM Camion domestico 138122
GM Importa auto 197
GM Importa camion 0
Honda Auto domestica 51450
Honda Camion domestico 46115
Honda Importa auto 2932
Honda Importa camion 0
Nissan Auto domestica 51476
Nissan Camion domestico 47343
Nissan Importa auto 5485
Nissan Importa camion 1430
Toyota Auto domestica 55643
Toyota Camion domestico 61227
Toyota Importa auto 20799
Toyota Importa camion 23614

L'oggetto visivo usa il mapping di visualizzazione dati seguente:

{
    "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"
                                }
                            }
                        ]
                    }
                }
            }
        }
    ]
}

Nell'esempio precedente è Manufacturercolumns e Type è rows. Una serie viene creata raggruppando i valori per rows (Type).

L'oggetto visivo deve essere in grado di filtrare i dati in base Manufacturer a o Type.

Ad esempio, se un utente seleziona Chrysler da Manufacturer, gli altri oggetti visivi devono mostrare i dati seguenti:

Produttore Tipo valore
Chrysler Auto domestica 28883
Chrysler Camion domestico 117131
Chrysler Importa auto 0
Chrysler Importa camion 6362

Quando l'utente seleziona Import Car per Type (seleziona i dati per serie), gli altri oggetti visivi devono mostrare i dati seguenti:

Produttore Tipo valore
Chrysler Importa auto 0
Ford Importa auto 0
GM Importa auto 197
Honda Importa auto 2932
Nissan Importa auto 5485
Toyota Importa auto 20799

Screenshot that shows the visual with selections.

Per visualizzare i dati sezionati, compilare i cestini dati dell'oggetto visivo come indicato di seguito:

Screenshot that shows visual's data baskets.

Nell'esempio precedente, Manufacturer è category (columns), è series (rows) Type e Sales è Values per la serie.

Nota

Values sono necessari per la visualizzazione di una serie perché, in base al mapping della vista dati, Values vengono raggruppati in Rows base ai dati.

Creare selezioni per le categorie

// 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);
}

Nel codice di esempio precedente viene eseguita l'iterazione di tutte le categorie. In ogni iterazione viene chiamato createSelectionIdBuilder per creare la selezione successiva per ogni categoria chiamando il withCategory metodo del generatore di selezione. Il createSelectionId metodo viene utilizzato come metodo finale per restituire l'oggetto generato selection .

withCategory Nel metodo viene passata la colonna di category, nell'esempio, il relativo Manufacturere l'indice dell'elemento category.

Creare selezioni per le serie

// 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);
});

Creare selezioni per il mapping delle viste dati della tabella

L'esempio seguente mostra il mapping della vista dati della tabella:

{
    "dataRoles": [
        {
            "displayName": "Values",
            "name": "values",
            "kind": "GroupingOrMeasure"
        }
    ],
    "dataViewMappings": [
        {
            "table": {
                "rows": {
                    "for": {
                        "in": "values"
                    }
                }
            }
        }
    ]
}

Per creare una selezione per ogni riga del mapping della vista dati della tabella, chiamare il withTable metodo del generatore di selezione.

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();
    }
}

Il codice visivo esegue l'iterazione delle righe della tabella e ogni riga chiama il withTable metodo table. I parametri del withTable metodo sono l'oggetto table e l'indice della riga della tabella.

Creare selezioni per il mapping delle visualizzazioni dati matrice

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);
            });
        }
    }
}

Nell'esempio chiama nodeWalker in modo ricorsivo ogni nodo e nodo figlio.

nodeWalker crea un nodeSelection oggetto in ogni chiamata. Ognuno nodeSelection rappresenta un selection oggetto dei nodi corrispondenti.

Selezionare i punti dati per filtrare altri oggetti visivi

In questo esempio è stato creato un gestore di clic per gli elementi del pulsante. Il gestore chiama il select metodo del gestore di selezione e passa l'oggetto di selezione.

button.addEventListener("click", () => {
    // handle click event to apply correspond selection
    this.selectionManager.select(categorySelectionId);
});

Interfaccia del select metodo :

interface ISelectionManager {
    // ...
    select(selectionId: ISelectionId | ISelectionId[], multiSelect?: boolean): IPromise<ISelectionId[]>;
    // ...
}

Il select metodo può accettare una matrice di selezioni. Ciò consente all'oggetto visivo di selezionare più punti dati contemporaneamente. Il secondo parametro, multiSelect, è responsabile delle selezioni multipla. Se multiSelect è true, Power BI non cancella lo stato di selezione precedente quando applica la selezione corrente. Se il valore è false, la selezione precedente viene sovrascritta.

Un esempio tipico di utilizzo multiSelect è la gestione dello stato del pulsante CTRL in un evento Click. Quando si tiene premuto il pulsante CTRL , è possibile selezionare più di un oggetto.

button.addEventListener("click", (mouseEvent) => {
    const multiSelect = (mouseEvent as MouseEvent).ctrlKey;
    this.selectionManager.select(seriesSelectionId, multiSelect);
});