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 |
Pour afficher des données en tranches, remplissez les paniers de données du visuel comme suit :
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);
});