教程:使用 React 创建 Power BI 视觉对象

  • 版本 :2023.1(当前版本)

教程:使用 React 创建 Power BI 视觉对象

作为开发人员,你可以创建自己的 Power BI 视觉对象。 这些视觉对象可供你、你的组织或第三方使用。

在本教程中,你将使用 React 开发 Power BI 视觉对象。 视觉对象显示一个圆圈内带格式的度量值。 视觉对象具有自适应大小并允许你对其设置进行自定义。

在本教程中,你将了解如何执行以下操作:

  • 为视觉对象创建开发项目。

  • 使用 React 开发视觉对象。

  • 配置视觉对象以处理数据。

  • 配置视觉对象以适应大小更改。

  • 配置视觉对象的自适应颜色和边框设置。

备注

有关此视觉对象的完整源代码,请参阅 React 圆形卡片 Power BI 视觉对象。

先决条件

在开始开发 Power BI 视觉对象之前,请验证本部分中是否已列出所有内容。

  • Power BI Pro 或 Premium Per User (PPU) 帐户 。 如果没有订阅密钥,可以注册免费试用版。

  • Visual Studio Code (VS Code)。 VS Code 是用于开发 JavaScript 和 TypeScript 应用程序的理想集成开发环境 (IDE)。

  • Windows PowerShell 版本 4 或更高版本(适用于 Windows)。 或终端(适用于 OSX)。

  • 准备好开发 Power BI 视觉对象的环境。 设置用于开发 Power BI 视觉对象的环境。

  • 本教程使用“美国销售额分析”报表。 你可以下载此报表并将其上传到 Power BI 服务,或使用自己的报表。 如果需要有关 Power BI 服务和上传文件的详细信息,请参阅开始在 Power BI 服务中创建教程。

创建开发项目

在本部分中,你将为 React 圆形卡片视觉对象创建项目。

  1. 打开 PowerShell 并导航到要在其中创建项目的文件夹。

  2. 输入以下命令:

    PowerShell复制

    pbiviz new ReactCircleCard
  3. 导航到项目的文件夹。

    PowerShell复制

    cd ReactCircleCard
  4. 启动 React 圆形卡片视觉对象。 托管在计算机上的视觉对象现在正在运行。

    PowerShell复制

    pbiviz start

    重要

    若要停止运行视觉对象,请在 PowerShell 中输入 Ctrl+C,若系统提示终止批处理作业,请输入 Y,然后按 Enter。

查看 Power BI 服务中的 React 圆形卡片

我们将使用“美国销售额分析”报表,以测试 Power BI 服务中的视觉对象。 你可以下载此报表并将其上传到 Power BI 服务。

你还可以使用自己的报表来测试视觉对象。

备注

在继续之前,请验证是否已启用视觉对象开发人员设置。

  1. 登录到 PowerBI.com 并打开“美国销售额分析”报表。

  2. 选择“编辑”。

    Power BI 服务中的“编辑”选项的屏幕截图。

  3. 通过单击 Power BI 服务界面底部的“新建页面”按钮,创建用于测试的新页面。

    Power BI 服务中的“新建页面”按钮的屏幕截图。

  4. 从“可视化效果”窗格中选择“开发人员视觉对象”。

    “可视化效果”窗格中的开发人员视觉对象的屏幕截图。

    此视觉对象表示在计算机上运行的自定义视觉对象。 仅当启用自定义视觉对象调试设置时,它才可用。

  5. 验证是否已向报表画布添加了视觉对象。

    已添加到报表中的新视觉对象的屏幕截图。

    这是一个非常简单的视觉对象,它显示了 update 方法调用的次数。 在此阶段,视觉对象尚未检索任何数据。

    备注

    如果视觉对象显示连接错误消息,请在浏览器中打开新选项卡,导航到 https://localhost:8080/assets,并授权浏览器使用此地址。

    显示连接错误的新视觉对象的屏幕截图。

  6. 选择新视觉对象的同时,转到“字段”窗格,展开“销售额”,然后选择“数量”。

    “美国销售额分析”报表的“销售额”表中的 Power BI 服务“数量”字段的屏幕截图。

  7. 若要测试视觉对象的响应方式,请调整其大小,并注意“更新计数”值会在每次调整视觉对象大小时递增。

    调整大小后显示不同更新计数的新视觉对象的屏幕截图。

在项目中设置 React

在本部分中,你将了解如何为 Power BI 视觉对象项目设置 React。

通过按 Ctrl+C,打开 PowerShell 并停止运行视觉对象。 出现提示时终止批处理作业,输入“Y”,然后按 Enter。

安装 React

若要安装所需的 React 依赖项,请在 ReactCircleCard 文件夹中打开 PowerShell,然后运行以下命令:

PowerShell复制

npm i react react-dom

安装 React 类型定义

若要安装 React 的类型定义,请在 reactCircleCard 文件夹中打开 PowerShell,然后运行以下命令:

PowerShell复制

npm i @types/react @types/react-dom

创建 React 组件类

按照以下步骤创建 React 组件类。

  1. 打开 VS Code,然后导航到 reactCircleCard 文件夹。

  2. 通过选择“文件”>“新建文件”来创建新的文件。

  3. 将以下代码复制到新的文件中。

    TypeScript复制

    import * as React from "react";export class ReactCircleCard extends React.Component{
    render(){ return (
    "circleCard">
    Hello, React!
    /div>
    )
    }
    }

    export default ReactCircleCard;
  4. 选择“另存为”,然后导航到 src 文件夹。

  5. 按如下所示保存文件:

    • 在“文件名”字段中,输入“component”。

    • 从“另存为类型”下拉菜单中,选择“TypeScript React”。

向视觉对象文件添加 React

将 visual.ts 文件中的代码替换为使用 React 启用的代码。

  1. 在 src 文件夹中,打开 visual.ts,然后将该文件中的代码替换为以下代码:

    TypeScript复制

    "use strict";import powerbi from "powerbi-visuals-api";import DataView = powerbi.DataView;import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;import IVisual = powerbi.extensibility.visual.IVisual;// Import React dependencies and the added componentimport * as React from "react";import * as ReactDOM from "react-dom";import ReactCircleCard from "./component";import "./../style/visual.less";export class Visual implements IVisual {    constructor(options: VisualConstructorOptions) {

    } public update(options: VisualUpdateOptions) {

    }
    }

    备注

    由于默认 Power BI TypeScript 设置无法识别 React tsx 文件,因此 VS Code 将 component 突出显示为错误。

  2. 若要呈现组件,请将目标 HTML 元素添加到 visual.ts。 此元素是 VisualConstructorOptions 中的 HTMLElement,该元素传递到构造函数中。

    TypeScript复制

    private target: HTMLElement;private reactRoot: React.ComponentElementany, any>;

    Typescript复制

    this.reactRoot = React.createElement(ReactCircleCard, {});this.target = options.element;

    ReactDOM.render(this.reactRoot, this.target);

    visual.ts 文件现在应如下所示:

    Typescript复制

    "use strict";import powerbi from "powerbi-visuals-api";import DataView = powerbi.DataView;import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;import IVisual = powerbi.extensibility.visual.IVisual;import * as React from "react";import * as ReactDOM from "react-dom";import ReactCircleCard from "./component";    

    import "./../style/visual.less";export class Visual implements IVisual { private target: HTMLElement; private reactRoot: React.ComponentElementany, any>; constructor(options: VisualConstructorOptions) { this.reactRoot = React.createElement(ReactCircleCard, {}); this.target = options.element;

    ReactDOM.render(this.reactRoot, this.target);
    } public update(options: VisualUpdateOptions) {

    }
    }
    1. 将以下行添加到 VisualConstructorOptions 构造函数:

    2. 在 src 文件夹中,打开 visual.ts。

    3. 将以下代码添加到 Visual 类:

  3. 保存 visual.ts。

编辑 tsconfig 文件

编辑 tsconfig.json 以使用 React。

  1. 在 reactCircleCard 文件夹中,打开 tsconfig.json,然后将两行添加到 compilerOptions 项的开头。

    JSON复制

    "jsx": "react","types": ["react", "react-dom"],

    tsconfig.json 文件现在应如下所示,而 visual.ts 中的 component 错误应消失。

    JSON复制

    {    "compilerOptions": {        "jsx": "react",        "types": ["react", "react-dom"],        "allowJs": false,        "emitDecoratorMetadata": true,        "experimentalDecorators": true,        "target": "es6",        "sourceMap": true,        "outDir": "./.tmp/build/",        "moduleResolution": "node",        "declaration": true,        "lib": [            "es2015",            "dom"
    ]
    }, "files": [ "./src/visual.ts"
    ]
    }
  2. 保存 tsconfig.json。

测试视觉对象

在 CircleCardVisual 文件夹中打开 PowerShell,然后运行项目:

Bash复制

pbiviz start

将新的“开发者视觉对象”添加到 Power BI 服务中的报表时,它将如下所示:

显示 Power BI 服务中新创建的开发者视觉对象中的 hello React 消息的屏幕截图。

配置视觉对象的数据字段

配置视觉对象的功能文件,以便只能将一个数据字段提交到视觉对象的“度量值数据”字段。

  1. 在 VS Code 的 reactCircleCard 文件夹中,打开 capabilities.json。

  2. ReactCircleCard 显示单个值 Measure Data。 从 dataRoles 类中删除 Category Data 对象。

    删除 Category Data 对象后,dataRoles 键如下所示:

    JSON复制

    "dataRoles": [
    { "displayName": "Measure Data", "name": "measure", "kind": "Measure"
    }
    ],
  3. 删除 objects 键的所有内容(稍后再进行填写)。

    删除其内容后,objects 键如下所示:

    JSON复制

    "objects": {},
  4. dataViewMappings 属性替换为以下代码。 measure 中的 max: 1 指定只能将一个数据字段提交到视觉对象的“度量值数据”字段。

    JSON复制

    "dataViewMappings": [
    { "conditions": [
    { "measure": { "max": 1
    }
    }
    ], "single": { "role": "measure"
    }
    }
    ]
  5. 保存对 capabilities.json 所做的更改。

  6. 验证 pbiviz start 是否正在运行,然后在 Power BI 服务中,刷新“React 圆形卡片”视觉对象。 “度量值数据”字段只能有一个数据字段,如 max: 1 所指定。

    显示 Power BI 服务的 React 圆形卡片中的“度量值数据”字段的屏幕截图。

更新视觉对象的样式

在本部分中,你会将视觉对象的形状变为圆形。 使用 visual.less 文件控制视觉对象的样式。

  1. 从 style 文件夹中,打开 visual.less。

  2. 将 visual.less 的内容替换为以下代码。

    css复制

    .circleCard {    position: relative;    box-sizing: border-box;    border: 1px solid #000;    border-radius: 50%;    width: 200px;    height: 200px;
    }p { text-align: center; line-height: 30px; font-size: 20px; font-weight: bold; position: relative; top: -30px; margin: 50% 0 0 0;
    }
  3. 保存 visual.less。

设置视觉对象以接收来自 Power BI 的属性

在本部分中,你将配置视觉对象以接收来自 Power BI 的数据,并将更新发送到 component.tsx 文件中的实例。

使用 React 呈现数据

可以使用 React 呈现数据。 组件可以显示来自其自身状态的数据。

  1. 在 VS Code 的 reactCircleCard 文件夹中,打开 component.tsx。

  2. 将 component.tsx 的内容替换为以下代码。

    Javascript复制

    import * as React from "react";export interface State {    textLabel: string,    textValue: string
    }export const initialState: State = { textLabel: "", textValue: ""}export class ReactCircleCard extends React.Component{}, State>{ constructor(props: any){ super(props); this.state = initialState;
    }

    render(){ const { textLabel, textValue } = this.state; return ( div className="circleCard">
    p>
    {textLabel} br/>
    em>{textValue}em>
    p>
    div>
    )
    }
    }
  3. 保存 component.tsx。

设置视觉对象以接收数据

视觉对象接收数据作为 update 方法的参数。 在本部分中,你将更新此方法以接收数据。

以下代码从 DataView 中选择 textLabeltextValue,如果数据存在,则更新组件状态。

  1. 在 VS Code 的 src 文件夹中,打开 visual.ts。

  2. 请使用以下代码替换 import ReactCircleCard from "./component"; 这一行:

    TypeScript复制

    import { ReactCircleCard, initialState } from "./component";
  3. 将以下代码添加到 update 方法中。

    TypeScript复制

    if(options.dataViews && options.dataViews[0]){    const dataView: DataView = options.dataViews[0];

    ReactCircleCard.update({
    textLabel: dataView.metadata.columns[0].displayName,
    textValue: dataView.single.value.toString()
    });
    } else { this.clear();
    }
  4. 通过在 update 方法后添加以下代码来创建 clear 方法。

    TypeScript复制

    private clear() {
    ReactCircleCard.update(initialState);
    }
  5. 保存 visual.ts

设置视觉对象以发送数据

在本部分中,你将更新视觉对象以将更新发送到 component 文件中的实例。

  1. 在 VS Code 的 src 文件夹中,打开 component.tsx。

  2. 将以下代码添加到 ReactCircleCard 类:

    TypeScript复制

    private static updateCallback: (data: object) => void = null;public static update(newState: State) {    if(typeof ReactCircleCard.updateCallback === 'function'){
    ReactCircleCard.updateCallback(newState);
    }
    }public state: State = initialState;public componentWillMount() {
    ReactCircleCard.updateCallback = (newState: State): void => { this.setState(newState); };
    }public componentWillUnmount() {
    ReactCircleCard.updateCallback = null;
    }
  3. 保存 component.tsx。

查看对视觉对象所做的更改

测试“React 圆形卡片”视觉对象以查看所做的更改。

  1. 验证 pbiviz start 是否正在运行,然后在 Power BI 服务中,刷新“React 圆形卡片”视觉对象。

  2. 将“销售额”添加到视觉对象的“度量值数据”字段。

Power BI 服务的“React 圆形卡片”视觉对象中显示的“销售额值”的屏幕截图。

让视觉对象可调

目前,视觉对象具有固定的宽度和高度。 若要使视觉对象的大小可调整,需要在 visual.ts 和 component.tsx 文件中定义 size 变量 。 在本部分中,你将让视觉对象可调。

完成本部分中所述的步骤后,视觉对象中的圆形直径将与最小宽度或高度大小相对应,并且可以在 Power BI 服务中调整其大小。

配置 visual.ts 文件

options 对象获取视觉对象视区的当前大小。

  1. 在 VS Code 的 src 文件夹中,打开 visual.ts。

  2. 插入此代码以导入 IViewport 接口。

    TypeScript复制

    import IViewport = powerbi.IViewport;
  3. viewport 属性添加到 visual 类。

    TypeScript复制

    private viewport: IViewport;
  4. update 方法中,在 ReactCircleCard.update 之前添加以下代码。

    TypeScript复制

    this.viewport = options.viewport;const { width, height } = this.viewport;const size = Math.min(width, height);
  5. update 方法中,在 ReactCircleCard.update 中添加 size

    TypeScript复制

    size,
  6. 保存 visual.ts。

配置 component.tsx 文件

  1. 在 VS Code 的 src 文件夹中,打开 component.tsx。

  2. 将以下代码添加到 export interface State

    TypeScript复制

    size: number
  3. 将以下代码添加到 export const initialState: State

    TypeScript复制

    size: 200
  4. render 方法中,执行以下操作:

    1. 已将 size 添加到 const { textLabel, textValue, size } = this.state;。 此声明现在应如下所示:

      TypeScript复制

      const { textLabel, textValue, size } = this.state;
    2. 将以下代码添加到 return 上方。

      TypeScript复制

      const style: React.CSSProperties = { width: size, height: size };
    3. 将第一个 return 行

      替换为:

      TypeScript复制

      "circleCard" style={style}>
  5. 保存 component.tsx。

配置 visual 文件

  1. 在 VS Code 的 style 文件夹中,打开 visual.less。

  2. .circleCard 中,将 widthheight 替换为 min-widthmin-height

    css复制

    min-width: 200px;min-height: 200px;
  3. 保存 visual.less。

使 Power BI 视觉对象可自定义

在本部分中,你将添加自定义视觉对象的功能,允许用户更改其颜色和边框宽度。

向功能文件添加颜色和粗细

向 capabilities.json 中的 object 属性添加颜色和边框粗细。

  1. 在 VS Code 的 reactCircleCard 文件夹中,打开 capabilities.json。

  2. 将以下设置添加到 objects 属性。

    JSON复制

    "circle": {    "properties": {       "circleColor": {            "type": {                "fill": {                    "solid": {                        "color": true
    }
    }
    }
    }, "circleThickness": { "type": { "numeric": true
    }
    }
    }
    }
  3. 保存 capabilities.json。

将圆形格式化设置类添加到设置文件

Circle 格式化设置添加到 settings.ts。 若要详细了解如何生成格式设置模型设置,请参阅格式设置 utils。

  1. 在 VS Code 的 src 文件夹中,打开 settings.ts。

  2. 将 settings.ts 中的代码替换为以下代码:

    TypeScript复制

    "use strict";import { formattingSettings } from "powerbi-visuals-utils-formattingmodel";import FormattingSettingsCard = formattingSettings.Card;import FormattingSettingsSlice = formattingSettings.Slice;import FormattingSettingsModel = formattingSettings.Model;/**
    * Circle Formatting Card
    */class CircleCardSettings extends FormattingSettingsCard {
    circleColor = new formattingSettings.ColorPicker({
    name: "circleColor", // circle color name should match circle color property name in capabilities.json
    displayName: "Color",
    description: "The fill color of the circle.",
    value: { value: "white" }
    });

    circleThickness = new formattingSettings.NumUpDown({
    name: "circleThickness", // circle thickness name should match circle color property name in capabilities.json
    displayName: "Thickness",
    description: "The circle thickness.",
    value: 2
    });

    name: string = "circle"; // circle card name should match circle object name in capabilities.json
    displayName: string = "Circle";
    slices: Array = [this.circleColor, this.circleThickness];
    }/**
    * visual settings model class
    *
    */export class VisualFormattingSettingsModel extends FormattingSettingsModel { // Create formatting settings model circle formatting card
    circleCard = new CircleCardSettings();

    cards = [this.circleCard];
    }
  3. 保存 settings.ts。

添加方法以应用视觉对象设置

将用于应用视觉对象设置的 getFormattingModel 方法和所需的导入添加到 visuals.ts 文件。

  1. 在 VS Code 的 src 文件夹中,打开 visuals.ts。

  2. 将这些 import 语句添加到 visual.ts 的顶部。

    TypeScript复制

    import { FormattingSettingsService } from "powerbi-visuals-utils-formattingmodel";import { VisualFormattingSettingsModel } from "./settings";
  3. 将以下声明添加到“视觉对象”。

    TypeScript复制

    private formattingSettings: VisualFormattingSettingsModel;private formattingSettingsService: FormattingSettingsService;
  4. getFormattingModel 方法添加到“视觉对象”。

    TypeScript复制

    public getFormattingModel(): powerbi.visuals.FormattingModel {    return this.formattingSettingsService.buildFormattingModel(this.formattingSettings);
    }
  5. Visual 类中,向 constructor 添加以下代码行以初始化 formattingSettingsService

    TypeScript复制

        this.formattingSettingsService = new FormattingSettingsService();
  6. Visual 类中,向 update 添加以下代码,以将视觉对象格式化设置更新到最新的格式设置属性值。

    1. 将此代码添加到 const size = Math.min(width, height); 后面的 if 语句。

      TypeScript复制

      this.formattingSettings = this.formattingSettingsService.populateFormattingSettingsModel(VisualFormattingSettingsModel, options.dataViews);const circleSettings = this.formattingSettings.circleCard;
    2. 将此代码添加到 size 之后的 ReactCircleCard.update 调用:

      TypeScript复制

      borderWidth: circleSettings.circleThickness.value,
      background: circleSettings.circleColor.value.value,
      }
  7. 保存 visual.ts。

编辑 component 文件

编辑 component 文件,以便可以呈现对视觉对象的颜色和边框粗细所做的更改。

  1. 在 VS Code 的 src 文件夹中,打开 component.tsx。

  2. 将这些值添加到 State

    TypeScript复制

    background?: string,
    borderWidth?: number
  3. render 方法中,替换以下代码行:

    1. const { textLabel, textValue, size } = this.state; 替换为:

      TypeScript复制

      const { textLabel, textValue, size, background, borderWidth } = this.state;
    2. const style: React.CSSProperties = { width: size, height: size }; 替换为:

      TypeScript复制

      const style: React.CSSProperties = { width: size, height: size, background, borderWidth };
  4. 保存 component.tsx。

查看你的更改

试验视觉对象的颜色和边框粗细,你现在可以对其进行控制。

  1. 验证 pbiviz start 是否正在运行,然后在 Power BI 服务中,刷新“React 圆形卡片”视觉对象。

  2. 选择“格式”选项卡,然后展开“圆形”。

  3. 调整视觉对象的“颜色”和“粗细”设置,然后查看它们对视觉对象的影响。

Power BI 服务中的“React 圆形卡片”视觉对象的屏幕截图,其中显示了颜色和边框粗细格式选项。