Power BI ビジュアルの選択によってビジュアルに対話機能を追加する
Power BI には、視覚化と対話する方法として、選択とフィルター処理の 2 つが用意されています。 次の例は、1 つの視覚化から項目を選択し、レポート内の他の視覚化に新しい選択状態について通知する方法を示しています。
インターフェイスは Selection
オブジェクトに対応しています。
export interface ISelectionId {
equals(other: ISelectionId): boolean;
includes(other: ISelectionId, ignoreHighlight?: boolean): boolean;
getKey(): string;
getSelector(): Selector;
getSelectorsByColumn(): SelectorsByColumn;
hasIdentity(): boolean;
}
選択マネージャーを使用してデータ ポイントを選択する
視覚化のホスト オブジェクトには、選択マネージャーのインスタンスを作成するためのメソッドが用意されています。 選択マネージャーには、次の各アクションに対応するメソッドがあります。
- 選択
- 選択のクリア
- コンテキスト メニューの表示
- 現在の選択内容の保存
- 選択状態の確認
選択マネージャーのインスタンスを作成する
選択マネージャーを使用するには、選択マネージャーのインスタンスを作成する必要があります。 通常は、視覚化によって、その視覚化オブジェクトの constructor
セクション内で選択マネージャーのインスタンスが作成されます。
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();
}
// ...
}
選択ビルダーのインスタンスを作成する
選択マネージャーのインスタンスを作成したら、そのビジュアルのデータ ポイントごとに selections
を作成する必要があります。 視覚化ホスト オブジェクトの createSelectionIdBuilder
メソッドを使って、各データ ポイントの選択を生成します。 このメソッドからは、インターフェイス 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;
}
このオブジェクトには、さまざまな種類のデータ ビュー マッピングの selections
を作成するための、対応するメソッドが備わっています。
注意
メソッド withTable
と withMatrixNode
は、Power BI ビジュアルの API 2.5.0 で導入されました。
テーブルまたはマトリックスのデータ ビュー マッピングに対する選択を使用する必要がある場合は、API バージョンを 2.5.0 以上に更新します。
カテゴリ別のデータ ビュー マッピングに対する選択を作成する
選択によって、サンプル セマンティック モデルのカテゴリ別のデータ ビュー マッピングがどのように表されるかを確認しましょう。
メーカー | 種類 | 値 |
---|---|---|
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 |
この視覚化では、次のデータ ビュー マッピングが使用されます。
{
"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"
}
}
]
}
}
}
}
]
}
上記の例では、Manufacturer
は columns
で、Type
は rows
です。 rows
(Type
) で値をグループ化することによって系列が作成されます。
ビジュアルでは、Manufacturer
または Type
によってデータをスライスすることもできます。
たとえば、ユーザーが Manufacturer
で Chrysler
を選択すると、他のビジュアルには次のデータが表示されます。
製造元 | 種類 | 値 |
---|---|---|
Chrysler | Domestic Car | 28883 |
Chrysler | Domestic Truck | 117131 |
Chrysler | Import Car | 0 |
Chrysler | Import Truck | 6362 |
ユーザーが Type
で Import Car
を選択 (系列でデータを選択) すると、他のビジュアルには次のデータが表示されます。
製造元 | 種類 | 値 |
---|---|---|
Chrysler | Import Car | 0 |
Ford | Import Car | 0 |
GM | Import Car | 197 |
Honda | Import Car | 2932 |
Nissan | Import Car | 5485 |
Toyota | Import Car | 20799 |
スライスされたデータを表示するには、視覚化のデータ バスケットを次のように設定します。
上記の例では、カテゴリ (列) として Manufacturer
が、系列 (行) として Type
が、系列の Values
として Sales
があります。
Note
Values
は系列を表示するために必要です。データ ビュー マッピングに従い、Values
が Rows
データ別にグループ化されるためです。
カテゴリに対する選択を作成する
// 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);
}
前のサンプル コードでは、すべてのカテゴリを反復処理しています。 それぞれの反復で、createSelectionIdBuilder
を呼び出し、その選択ビルダーの withCategory
メソッドを呼び出すことで各カテゴリに対する次の選択を作成しています。 createSelectionId
メソッドは、生成された selection
オブジェクトを返すための最後のメソッドとして使用されています。
withCategory
メソッドには、category
の列 (このサンプルでは Manufacturer
) と、カテゴリ要素のインデックスを渡します。
系列に対する選択を作成する
// 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);
});
テーブルのデータ ビュー マッピングに対する選択を作成する
次の例は、テーブル データ ビューのマッピングを示しています。
{
"dataRoles": [
{
"displayName": "Values",
"name": "values",
"kind": "GroupingOrMeasure"
}
],
"dataViewMappings": [
{
"table": {
"rows": {
"for": {
"in": "values"
}
}
}
}
]
}
テーブルのデータ ビュー マッピングの各行に対する選択を作成するには、選択ビルダーの withTable
メソッドを呼び出します。
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();
}
}
ビジュアルのコードでは、テーブルの行が反復処理され、各行で withTable
テーブル メソッドが呼び出されます。 withTable
メソッドのパラメーターは、table
オブジェクトと、テーブル行のインデックスです。
マトリックスのデータ ビュー マッピングに対する選択を作成する
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);
});
}
}
}
このサンプルでは、nodeWalker
が各ノードと子ノードを再帰的に呼び出します。
nodeWalker
は、呼び出されるごとに nodeSelection
オブジェクトを作成します。 それぞれの nodeSelection
が対応するノードの selection
を表します。
データ ポイントを選択して他のビジュアルをスライスする
次の例では、ボタン要素のクリック ハンドラーを作成しました。 このハンドラーでは、選択マネージャーの select
メソッドが呼び出されて選択オブジェクトが渡されます。
button.addEventListener("click", () => {
// handle click event to apply correspond selection
this.selectionManager.select(categorySelectionId);
});
select
メソッドのインターフェイスは次のとおりです。
interface ISelectionManager {
// ...
select(selectionId: ISelectionId | ISelectionId[], multiSelect?: boolean): IPromise<ISelectionId[]>;
// ...
}
select
メソッドには選択の配列を指定できます。 これにより、ビジュアルで一度に複数のデータ ポイントを選択できます。 2 番目のパラメーター multiSelect
を使用して、複数選択を行います。 multiSelect
が true の場合、Power BI では現在の選択を適用するときに、前の選択状態をクリアしません。 この値が false の場合、前の選択は上書きされます。
multiSelect
を使用する一般的な例は、クリック イベント時の Ctrl ボタンの状態の処理です。 Ctrl ボタンを押した状態だと、複数のオブジェクトを選択できます。
button.addEventListener("click", (mouseEvent) => {
const multiSelect = (mouseEvent as MouseEvent).ctrlKey;
this.selectionManager.select(seriesSelectionId, multiSelect);
});