为 Power BI 视觉对象创建对话框
创建视觉对象时,有时最好在单独的窗口中向客户显示附加消息。 例如,您可能希望:
- 显示附加消息 - 例如文本注释或视频
- 显示输入数据对话框 - 例如日期对话框
为此,可以创建一个对话视觉对象弹出窗口,在本文中称为“对话框”。
对话框注意事项
为视觉对象创建对话框时,请注意以下事项:
- 在开发过程中,可以指定对话框的大小和位置。
- 当触发对话框时,报表背景将灰显。
- 对话框标题包含视觉对象的图标及其显示名称作为标题。
- 此对话框最多可以有三个操作按钮。 你可以选择要在给定选择中显示的按钮。
- 此对话框使用 Rich HTML
iframe
。 - 显示对话框时,无法在报表中执行任何操作,直到关闭对话框。
- 对话框代码可以使用外部 npm 库,就像视觉对象一样。
重要
不应自发触发对话框。 它应是用户操作的直接结果。
为视觉对象设计对话框
若要配置对话框,需要将两个组件添加到代码中:
- 实现文件 - 最佳做法是为每个对话框创建一个实现文件。
- 用于调用对话框的代码 - 若要调用对话框,请向
visual.ts
文件添加代码。
创建对话框实现文件
建议为创建的每个对话框创建实现文件。 将对话框文件置于 src
文件夹中:
每个对话框实现文件应包括以下组件:
创建对话框类
为对话框创建对话框类。 openModalDialog
中的 initialState
参数在创建时便传递给对话框承包商。 使用 initialState
对象将参数传递给对话框,以影响其行为或外观。
对话代码可以使用以下 IDialogHost
方法:
IDialogHost.setResult(result:object)
- 对话代码会返回一个结果对象,该对象会被传回发起调用的视觉对象。IDialogHost.close(actionId: DialogAction, result?:object)
- 对话代码可以编程方式关闭对话,并将结果对象提供回其调用视觉对象。
在文件顶部导入:
import powerbi from "powerbi-visuals-api";
import DialogConstructorOptions = powerbi.extensibility.visual.DialogConstructorOptions;
import DialogAction = powerbi.DialogAction;
// React imports as an example
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import reactDatepicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
此示例需要安装以下包:
npm i react-dom react react-datepicker
类实现:
export class DatePickerDialog {
static id = "DatePickerDialog";
constructor(options: DialogConstructorOptions, initialState: object) {
const host = options.host;
let pickedDate: Date;
const startDate = new Date(initialState['startDate']);
// Dialog rendering implementation
ReactDOM.render(
React.createElement(
reactDatepicker,
{
inline: true,
openToDate: startDate,
onChange: (date: Date) => {
pickedDate = date
host.setResult({ date: pickedDate })
}
},
null),
options.element
);
document.addEventListener('keydown', e => {
if (e.code == 'Enter' && pickedDate) {
host.close(DialogAction.Close, {date: pickedDate});
}
});
}
}
创建结果类
创建返回对话框结果的类,然后将其添加到对话框实现文件。
在下面的示例中,DatePickerDialogResult
类返回日期字符串。
export class DatePickerDialogResult {
date: string;
}
将对话框添加到注册表列表
每个对话框实现文件都需要包含注册表引用。 将以下示例中的两行添加到你的对话框实现文件的末尾。 每个对话框实现文件的第一行应该是相同的。 第二行列出对话框;可根据对话框类的名称进行修改。
globalThis.dialogRegistry = globalThis.dialogRegistry || {};
globalThis.dialogRegistry[DatePickerDialog.id] = DatePickerDialog;
调用对话框
在创建对话框之前,需决定它将包含哪些按钮。 Power BI 视觉对象支持以下六个对话框按钮:
export enum DialogAction {
Close = 0,
OK = 1,
Cancel = 2,
Continue = 3,
No = 4,
Yes = 5
}
需在 visual.ts
文件中调用所创建的每个对话框。 在本例中,对话框由两个操作按钮定义。
import powerbi from "powerbi-visuals-api";
import DialogAction = powerbi.DialogAction;
const dialogActionsButtons = [DialogAction.OK, DialogAction.Cancel];
在本例中,通过单击视觉对象按钮调用对话框。 视觉对象按钮被定义为 visual.ts
文件中视觉对象构造函数的一部分。
定义对话框的大小和位置
在 API 版本 4.0 或更高版本中,可使用 openModalDialog
的 DialogOpenOptions
参数定义对话框的大小和位置。 若要了解正在使用的版本,请检查 pbiviz.json 文件中的 apiVersion
。
export interface RectSize {
width: number;
height: number;
}
export interface DialogOpenOptions {
title: string;
size?: RectSize;
position?: VisualDialogPosition;
actionButtons: DialogAction[];
}
position 参数可用于确定对话框应在屏幕上打开的位置。 可选择在屏幕中心打开对话框,也可定义相对于视觉对象的不同位置。
const enum VisualDialogPositionType {
Center = 0,
RelativeToVisual = 1
}
export interface VisualDialogPosition {
type: VisualDialogPositionType;
left?: number;
top?: number;
}
- 如果未指定类型,则默认在中间打开对话框。
- 位置以像素为单位,与视觉对象的左上角相对。
此示例显示一个 250 x 300 像素的日期选择对话框,该对话框左侧为 100 像素,视觉对象顶部下方为 30 像素:
export class Visual implements IVisual {
private target: HTMLElement;
private host: IVisualHost;
constructor(options: VisualConstructorOptions) {
this.host = options.host;
this.target = options.element;
const dialogActionsButtons = [DialogAction.OK, DialogAction.Cancel];
const sectionDiv = document.createElement("div");
const span = document.createElement("span");
span.id = "datePicker";
let button = document.createElement("button");
button.id = "DateButton";
button.innerText = "Date";
button.onclick = (event) => {
const initialDialogState = { startDate: new Date() };
const position = {
type: VisualDialogPositionType.RelativeToVisual,
left: 100,
top: 30
};
const size = {width: 250, height: 300};
const dialogOptions = {
actionButtons: dialogActionsButtons,
size: size,
position: position,
title: "Select a date"
};
this.host.openModalDialog(DatePickerDialog.id, dialogOptions, initialDialogState).
then(ret => this.handleDialogResult(ret, span)).
catch(error => this.handleDialogError(error, span));
}
sectionDiv.appendChild(button);
sectionDiv.appendChild(span);
this.target.appendChild(sectionDiv)
}
// Custom logic to handle dialog results
private handleDialogResult( result: ModalDialogResult, targetElement: HTMLElement){
if ( result.actionId === DialogAction.OK || result.actionId === DialogAction.Close) {
const resultState = <DatePickerDialogResult> result.resultState;
const selectedDate = new Date(resultState.date);
targetElement.textContent = selectedDate.toDateString();
}
}
// Custom logic to handle errors in dialog
private handleDialogError( error: any, targetElement: HTMLElement ) {
targetElement.textContent = "Error: " + JSON.stringify(error);
}
}
定义如何关闭对话框
关闭对话框的首选方法是最终用户单击 [x] 按钮、操作按钮之一或报表背景。
还可以通过调用 IDialogHost
close 方法将对话框编程为自动关闭。 对话框打开后,此方法将被阻止五秒,因此,最早可以在对话框启动后五秒自动关闭该对话框。
“不显示”对话框
对话框与复选框一起出现,该复选框为用户提供了用于阻止对话框的选项。
此复选框是一项安全功能,可防止视觉对象在用户不同意的情况下创建模式对话框(无论是有意还是无意)。
此阻止仅对当前会话有效。 因此,如果用户阻止了 CV 模式对话,但后来改变了主意,他们可以重新启用对话。 要执行此操作,他们需要启动新会话(刷新 Power BI 服务中的报表页或重启 Power BI Desktop)。
注意事项和限制
自 powerbi-visuals-API 3.8 起,对话框图标和标题由视觉对象的图标和显示名称决定,且无法更改。
对话框的大小限制如下表所示。
最大/最小 宽度 高度 最大值 浏览器宽度的 90% 浏览器高度的 90% 最小值 240 磅 210 px 定义对话框的位置时,水平位置可以是正整数或负整数,具体取决于你希望框位于视觉对象的哪一侧。 垂直位置不能为负,以避免放在视觉对象的上方。
以下功能不支持 Power BI 视觉对象对话框:
- 嵌入式分析
- 发布到 Web
- 仪表板
可以通过检查布尔值 this.host.hostCapabilities.allowModalDialog
来对视觉对象进行编程,以检测当前环境是否允许打开对话框。