Ajoutez de l'interactivité à vos visuels grâce à des sélections de visuels Power BI

Power BI propose deux façons d’interagir avec les visuels : la sélection et le filtrage. L’exemple suivant montre comment sélectionner un élément dans un visuel et informer les autres visuels du rapport du nouvel état de sélection.

L’interface correspond à un objet Selection :

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

Utiliser le gestionnaire de sélection pour sélectionner des points de données

L’objet hôte visuel fournit la méthode pour créer une instance du gestionnaire de sélection. Le gestionnaire de sélection a une méthode correspondante pour chacune des actions suivantes :

  • Sélectionnez
  • Effacer la sélection
  • Afficher le menu contextuel
  • Mémoriser les sélections actuelles
  • Vérifier l’état de la sélection

Créer une instance de gestionnaire de sélection

Pour utiliser le gestionnaire de sélection, créez l’instance d’un gestionnaire de sélection. Les visuels créent généralement une instance du gestionnaire de sélection dans la section constructor de l’objet visuel.

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

Créer une instance de générateur de sélection

Lorsque l'instance du gestionnaire de sélection est créée, vous devez créer selections pour chaque point de données du visuel. La méthode createSelectionIdBuilder de l’objet hôte du visuel génère une sélection pour chaque point de données. Cette méthode retourne l’instance de l’objet avec l’interface 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;
}

Cet objet propose des méthodes correspondantes afin de créer selections pour différents types de mappages de vues de données.

Notes

Les méthodes withTable et withMatrixNode ont été introduites dans l’API 2.5.0 des visuels Power BI. Si vous avez besoin d’utiliser des sélections pour des mappages de vues de données de tables ou de matrices, mettez à jour l’API vers la version 2.5.0 ou supérieure.

Créer des sélections pour le mappage de vues de données catégoriques

Examinons comment les sélections sont représentées sur le mappage de vues de données catégoriques pour un exemple de modèle sémantique :

Fabricant Type Valeur
Chrysler Voiture nationale 28883
Chrysler Camion national 117131
Chrysler Véhicule d’importation 0
Chrysler Camion d’importation 6362
Ford Voiture nationale 50032
Ford Camion national 122446
Ford Véhicule d’importation 0
Ford Camion d’importation 0
GM Voiture nationale 65426
GM Camion national 138122
GM Véhicule d’importation 197
GM Camion d’importation 0
Honda Voiture nationale 51450
Honda Camion national 46115
Honda Véhicule d’importation 2932
Honda Camion d’importation 0
Nissan Voiture nationale 51476
Nissan Camion national 47343
Nissan Véhicule d’importation 5485
Nissan Camion d’importation 1430
Toyota Voiture nationale 55643
Toyota Camion national 61227
Toyota Véhicule d’importation 20799
Toyota Camion d’importation 23614

Le visuel utilise le mappage de vues de données suivant :

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

Dans l’exemple précédent, Manufacturer correspond à columns et Type à rows. Une série est créée en regroupant les valeurs par rows (Type).

Le visuel doit pouvoir découper les données par Manufacturer ou Type.

Par exemple, si l’utilisateur sélectionne Chrysler par Manufacturer, les autres visuels doivent afficher les données suivantes :

Fabricant Type Valeur
Chrysler Voiture nationale 28883
Chrysler Camion national 117131
Chrysler Véhicule d’importation 0
Chrysler Camion d’importation 6362

Lorsque l’utilisateur sélectionne Import Car par Type (sélectionne les données par série), les autres visuels doivent afficher les données suivantes :

Fabricant Type Valeur
Chrysler Véhicule d’importation 0
Ford Véhicule d’importation 0
GM Véhicule d’importation 197
Honda Véhicule d’importation 2932
Nissan Véhicule d’importation 5485
Toyota Véhicule d’importation 20799

Screenshot that shows the visual with selections.

Pour afficher des données en tranches, remplissez les paniers de données du visuel comme suit :

Screenshot that shows visual's data baskets.

Dans l’exemple précédent, Manufacturer est une catégorie (colonnes), Type est une série (lignes) et Sales est Values pour série.

Notes

Les Values sont nécessaires pour afficher une série car, selon le mappage de la vue des données, les Values sont regroupés par données Rows.

Créer des sélections pour des catégories

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

Dans l’exemple de code précédent, nous itérons à travers toutes les catégories. Dans chaque itération, nous appelons createSelectionIdBuilder afin de créer la sélection suivante pour chaque catégorie en appelant la méthode withCategory du générateur de sélection. La méthode createSelectionId est utilisée comme méthode finale pour retourner l’objet selection généré.

Dans la méthode withCategory, nous passons la colonne de category, Manufacturer dans cet exemple, et l’index d’un élément de catégorie.

Créer des sélections pour les séries

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

Créer des sélections pour le mappage de vues de données de tables

L’exemple suivant montre le mappage des vues de données de table :

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

Afin de créer une sélection pour chaque ligne d’un mappage de vues de données de tables, appelez la méthode withTable du générateur de sélection.

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

Le code visuel itère les lignes de la table, et chaque ligne appelle la méthode de table withTable. Les paramètres de la méthode withTable représentent l’objet table et l’index de la ligne de la table.

Créer des sélections pour le mappage de vues de données de matrices

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

Dans l’exemple, nodeWalker appelle récursivement chaque nœud et nœud enfant.

nodeWalker crée un objet nodeSelection à chaque appel. Chaque nodeSelection représente un selection des nœuds correspondants.

Sélectionner des points de données pour découper d’autres visuels

Dans cet exemple, nous avons créé un gestionnaire de clics pour les éléments de type bouton. Le gestionnaire appelle la méthode select du gestionnaire de sélection et passe l’objet de sélection.

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

L’interface de la méthode select :

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

La méthode select peut accepter un tableau de sélections. Cela permet à votre visuel d’avoir plusieurs points de données sélectionnés en même temps. Le deuxième paramètre, multiSelect, est responsable des sélections multiples. Si multiSelect est true, Power BI n’efface pas l’état de la sélection précédente lorsqu’il applique la sélection actuelle. Si la valeur est false, la sélection précédente est remplacée.

La manipulation de la touche Ctrl lors d’un événement Click est un exemple typique d’utilisation de multiSelect. Lorsque la touche Ctrl est maintenue enfoncée, vous pouvez sélectionner plusieurs objets.

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