Aggiungere interattività negli oggetti visivi tramite le 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 oggetto Selection
:
export interface ISelectionId {
equals(other: ISelectionId): boolean;
includes(other: ISelectionId, ignoreHighlight?: boolean): boolean;
getKey(): string;
getSelector(): Selector;
getSelectorsByColumn(): SelectorsByColumn;
hasIdentity(): boolean;
}
Come usare la gestione selezione per selezionare i punti dati
L'oggetto host dell'oggetto visivo fornisce un metodo per la creazione di un'istanza di gestione selezione. La gestione selezione dispone di un metodo corrispondente per ognuna delle azioni seguenti:
- Seleziona
- Cancellare la selezione
- Mostrare il menu di scelta rapida
- Archiviare le selezioni correnti
- Controllare lo stato selezione
Creare un'istanza della gestione selezione
Per usare la gestione selezione, creare la relativa istanza. Gli oggetti visivi creano in genere un'istanza di gestione selezione nella sezione constructor
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 createSelectionIdBuilder
dell'oggetto host visivo genera una selezione per ciascun punto dati. Questo metodo restituisce un'istanza dell'oggetto con l'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 ha metodi corrispondenti per creare selections
per diversi tipi di mapping di visualizzazione 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 visualizzazione dati di tabella o di matrice, aggiornare l'API alla 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 dei dati categoriche per un modello semantico di esempio:
Produttore | Type | Valore |
---|---|---|
Chrysler | Domestic Car | 28883 |
Chrysler | Domestic Truck | 117131 |
Chrysler | Import Car | 0 |
Chrysler | Import Truck | 6362 |
Ford | Domestic Car | 50032 |
Ford | Domestic Truck | 122446 |
Ford | Import Car | 0 |
Ford | Import Truck | 0 |
GM | Domestic Car | 65426 |
GM | Domestic Truck | 138122 |
GM | Import Car | 197 |
GM | Import Truck | 0 |
Honda | Domestic Car | 51450 |
Honda | Domestic Truck | 46115 |
Honda | Import Car | 2932 |
Honda | Import Truck | 0 |
Nissan | Domestic Car | 51476 |
Nissan | Domestic Truck | 47343 |
Nissan | Import Car | 5485 |
Nissan | Import Truck | 1430 |
Toyota | Domestic Car | 55643 |
Toyota | Domestic Truck | 61227 |
Toyota | Import Car | 20799 |
Toyota | Import Truck | 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 Manufacturer
è columns
e Type
è rows
. Viene creata una serie da valori di raggruppamento per rows
(Type
).
L'oggetto visivo deve essere in grado di suddividere i dati in base a Manufacturer
o Type
.
Ad esempio, se un utente seleziona Chrysler
per Manufacturer
, gli altri oggetti visivi devono mostrare i dati seguenti:
Produttore | Type | Valore |
---|---|---|
Chrysler | Domestic Car | 28883 |
Chrysler | Domestic Truck | 117131 |
Chrysler | Import Car | 0 |
Chrysler | Import Truck | 6362 |
Quando l'utente seleziona Import Car
per Type
(seleziona i dati in base alla serie), gli altri oggetti visivi visualizzano i dati seguenti:
Produttore | Type | Valore |
---|---|---|
Chrysler | Import Car | 0 |
Ford | Import Car | 0 |
GM | Import Car | 197 |
Honda | Import Car | 2932 |
Nissan | Import Car | 5485 |
Toyota | Import Car | 20799 |
Per visualizzare i dati sezionati, compilare le tabelle di dati dell'oggetto visivo come indicato di seguito:
Nell'esempio precedente, Manufacturer
è una categoria (colonne), Type
è una serie (righe) 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
sono raggruppati per dati Rows
.
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, si chiama createSelectionIdBuilder
per creare la selezione successiva per ogni categoria chiamando il metodo withCategory
del generatore di selezione. Il metodo createSelectionId
viene usato come metodo finale per restituire l'oggetto selection
generato.
Nel metodo withCategory
, viene passata la colonna di category
, nell'esempio si tratta di Manufacturer
e dell'indice dell'elemento categoria.
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 di visualizzazione dati di tabella
L'esempio seguente mostra il mapping della visualizzazione dei 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 di visualizzazione dei dati della tabella, chiamare il metodo withTable
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 metodo tabella withTable
. I parametri del metodo withTable
sono l'oggetto table
e l'indice della riga della tabella.
Creare selezioni per il mapping di visualizzazione dati di 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, nodeWalker
esegue chiamate in modo ricorsivo per ogni nodo e nodo figlio.
nodeWalker
crea un oggetto nodeSelection
a ogni chiamata. Ogni nodeSelection
rappresenta un selection
di nodi corrispondenti.
Selezionare i punti dati per suddividere altri oggetti visivi
In questo esempio, è stato creato un gestore di clic per gli elementi del pulsante. Il gestore chiama il metodo select
di gestione selezione e passa l'oggetto di selezione.
button.addEventListener("click", () => {
// handle click event to apply correspond selection
this.selectionManager.select(categorySelectionId);
});
L'interfaccia del metodo select
:
interface ISelectionManager {
// ...
select(selectionId: ISelectionId | ISelectionId[], multiSelect?: boolean): IPromise<ISelectionId[]>;
// ...
}
Il metodo select
può accettare una matrice di selezioni. Ciò consente all'oggetto visivo di disporre di più punti dati contemporaneamente. Il secondo parametro, multiSelect
, è responsabile della selezione 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 dell'uso di multiSelect
consiste nel gestire lo stato del pulsante CTRL in un evento clic. 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);
});