通过 Power BI 视觉对象选择将交互性添加到视觉对象
- 版本 :2023.1(当前版本)
通过 Power BI 视觉对象选择将交互性添加到视觉对象
Power BI 提供了两种与视觉对象交互的方式 - 选择和筛选。 下面的示例演示如何从一个视觉对象中选择一个项,并就新的选择状态通知报表中的其他视觉对象。
接口对应于一个 Selection 对象:
TypeScript复制
export interface ISelectionId {
equals(other: ISelectionId): boolean;
includes(other: ISelectionId, ignoreHighlight?: boolean): boolean;
getKey(): string;
getSelector(): Selector;
getSelectorsByColumn(): SelectorsByColumn;
hasIdentity(): boolean;
}
如何使用 SelectionManager 选择数据点
视觉宿主对象提供创建选择管理器实例的方法。 选择管理器为以下每个操作提供相应方法:
Select
清除选择
显示上下文菜单
存储当前所选内容
检查选择状态
创建选择管理器的实例
要使用选择管理器,请创建选择管理器实例。 通常,视觉对象会在可视对象的 constructor 部分创建选择管理器实例。
TypeScript复制
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 接口的对象实例:
TypeScript复制
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 的对应方法。
备注
在 Power BI 视觉对象的 API 2.5.0 上引入了 withTable 和 withMatrixNode 方法。 如果需要将选择用于表或矩阵数据视图映射,则需要将 API 版本更新为 2.5.0 或更高版本。
为分类数据视图映射创建选择
让我们回顾一下选择如何表示示例数据集的分类数据视图映射:
| 制造商 | 类型 | 值 |
|---|---|---|
| Chrysler | 国产汽车 | 28883 |
| Chrysler | 国产卡车 | 117131 |
| Chrysler | 进口汽车 | 0 |
| Chrysler | 进口卡车 | 6362 |
| Ford | 国产汽车 | 50032 |
| Ford | 国产卡车 | 122446 |
| Ford | 进口汽车 | 0 |
| Ford | 进口卡车 | 0 |
| GM | 国产汽车 | 65426 |
| GM | 国产卡车 | 138122 |
| GM | 进口汽车 | 197 |
| GM | 进口卡车 | 0 |
| Honda | 国产汽车 | 51450 |
| Honda | 国产卡车 | 46115 |
| Honda | 进口汽车 | 2932 |
| Honda | 进口卡车 | 0 |
| Nissan | 国产汽车 | 51476 |
| Nissan | 国产卡车 | 47343 |
| Nissan | 进口汽车 | 5485 |
| Nissan | 进口卡车 | 1430 |
| Toyota | 国产汽车 | 55643 |
| Toyota | 国产卡车 | 61227 |
| Toyota | 进口汽车 | 20799 |
| Toyota | 进口卡车 | 23614 |
视觉对象使用以下数据视图映射:
JSON复制
{ "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 | 国产汽车 | 28883 |
| Chrysler | 国产卡车 | 117131 |
| Chrysler | 进口汽车 | 0 |
| Chrysler | 进口卡车 | 6362 |
当用户按 Type 选择 Import Car 时(按序列选择数据),其他视觉对象应显示以下数据:
| 制造商 | 类型 | 值 |
|---|---|---|
| Chrysler | 进口汽车 | 0 |
| Ford | 进口汽车 | 0 |
| GM | 进口汽车 | 197 |
| Honda | 进口汽车 | 2932 |
| Nissan | 进口汽车 | 5485 |
| Toyota | 进口汽车 | 20799 |

若要显示切片数据,请填充视觉对象的数据篮,如下所示:

在上述示例中,Manufacturer 为类别(列)、Type 为序列(行),而 Sales 为序列的 Values。
备注
Values 是显示序列所必需的,因为根据数据视图映射,Values 按 Rows 数据分组。
为类别创建选择
TypeScript复制
// categoriesconst categories = dataView.categorical.categories;// create label for 'Manufacturer' columnconst p = document.createElement("p") as HTMLParagraphElement;
p.innerText = categories[0].source.displayName.toString();this.target.appendChild(p);// get count of category elementsconst categoriesCount = categories[0].values.length;// iterate all categories to generate selection and create button elements to use selectionsfor (let categoryIndex = 0; 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);
}
在以上示例代码中,我们将遍历所有类别。 每次迭代时,我们都会通过调用选择生成器的 withCategory 方法调用 createSelectionIdBuilder 来为每个类别创建下一个选择。 createSelectionId 方法用作返回生成的 selection 对象的最终方法。
在 withCategory 方法中,我们将传递 category 列,在示例中为 Manufacturer,也是类别元素的索引。
为序列创建选择
TypeScript复制
// get groupped values for seriesconst series: powerbi.DataViewValueColumnGroup[] = dataView.categorical.values.grouped();// create label for 'Type' columnconst 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 selectionsseries.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);
});
为表数据视图映射创建选择
表数据视图映射示例:
JSON复制
{ "dataRoles": [
{ "displayName": "Values", "name": "values", "kind": "GroupingOrMeasure"
}
], "dataViewMappings": [
{ "table": { "rows": { "for": { "in": "values"
}
}
}
}
]
}
若要为表数据视图映射的每一行创建选择,请调用选择生成器的 withTable 方法。
TypeScript复制
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 对象和索引。
为矩阵数据视图映射创建选择
TypeScript复制
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 方法,并传递选择对象。
TypeScript复制
button.addEventListener("click", () => { // handle click event to apply correspond selection
this.selectionManager.select(categorySelectionId);
});
select 方法的接口是
TypeScript复制
interface ISelectionManager { // ...
select(selectionId: ISelectionId | ISelectionId[], multiSelect?: boolean): IPromise; // ...}
select 方法可以接受选择的数组。 这样,视觉对象可以同时选择多个数据点。 第二个参数 multiSelect 负责多选。 如果 multiSelect 为 true,则 Power BI 在应用当前选择时不会清除以前的选择状态。 如果值为 false,则覆盖上一个选择。
使用 multiSelect 的典型示例是处理单击事件上的 CTRL 按钮状态。 按下 CTRL 按钮时,可以选择多个对象。
TypeScript复制
button.addEventListener("click", (mouseEvent) => { const multiSelect = (mouseEvent as MouseEvent).ctrlKey;
this.selectionManager.select(seriesSelectionId, multiSelect);
});
400 998 0226
Tableau
Tableau
Minitab

Alteryx











Neo4j











Talend


















IM
华为云
腾讯云
IT/安全