选择“编辑”。
在项目中设置 React
在本部分中,你将了解如何为 Power BI 视觉对象项目设置 React。
通过按 Ctrl+C,打开 PowerShell 并停止运行视觉对象。 出现提示时终止批处理作业,输入“Y”,然后按 Enter。
安装 React
若要安装所需的 React 依赖项,请在 ReactCircleCard 文件夹中打开 PowerShell,然后运行以下命令:
npm i react react-dom
安装 React 类型定义
若要安装 React 的类型定义,请在 reactCircleCard 文件夹中打开 PowerShell,然后运行以下命令:
npm i @types/react @types/react-dom
创建 React 组件类
按照以下步骤创建 React 组件类。
打开 VS Code,然后导航到 reactCircleCard 文件夹。
通过选择“文件”>“新建文件”来创建新的文件。
将以下代码复制到新的文件中。
import * as React from "react";
export class ReactCircleCard extends React.Component<{}>{
render(){
return (
<div className="circleCard">
Hello, React!
export default ReactCircleCard;
选择“另存为”,然后导航到 src 文件夹。
按如下所示保存文件:
在“文件名”字段中,输入“component”。
从“另存为类型”下拉菜单中,选择“TypeScript React”。
向视觉对象文件添加 React
将 visual.ts 文件中的代码替换为使用 React 启用的代码。
在 src 文件夹中,打开 visual.ts,然后将该文件中的代码替换为以下代码:
"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 component
import * 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 突出显示为错误。
若要呈现组件,请将目标 HTML 元素添加到 visual.ts。 此元素是 VisualConstructorOptions 中的 HTMLElement,该元素传递到构造函数中。
在 src 文件夹中,打开 visual.ts。
将以下代码添加到 Visual 类:
private target: HTMLElement;
private reactRoot: React.ComponentElement<any, any>;
将以下行添加到 VisualConstructorOptions 构造函数:
this.reactRoot = React.createElement(ReactCircleCard, {});
this.target = options.element;
ReactDOM.render(this.reactRoot, this.target);
visual.ts 文件现在应如下所示:
"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.ComponentElement<any, any>;
constructor(options: VisualConstructorOptions) {
this.reactRoot = React.createElement(ReactCircleCard, {});
this.target = options.element;
ReactDOM.render(this.reactRoot, this.target);
public update(options: VisualUpdateOptions) {
保存 visual.ts。
编辑 tsconfig 文件
编辑 tsconfig.json 以使用 React。
在 reactCircleCard 文件夹中,打开 tsconfig.json,然后将两行添加到 compilerOptions 项的开头。
"jsx": "react",
"types": ["react", "react-dom"],
tsconfig.json 文件现在应如下所示,而 visual.ts 中的 component 错误应消失。
"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"
保存 tsconfig.json。
测试视觉对象
在 CircleCardVisual 文件夹中打开 PowerShell,然后运行项目:
pbiviz start
将新的“开发者视觉对象”添加到 Power BI 服务中的报表时,它将如下所示:
配置视觉对象的功能文件,以便只能将一个数据字段提交到视觉对象的“度量值数据”字段。
在 VS Code 的 reactCircleCard 文件夹中,打开 capabilities.json。
ReactCircleCard 显示单个值 Measure Data。 从 dataRoles 类中删除 Category Data 对象。
删除 Category Data 对象后,dataRoles 键如下所示:
"dataRoles": [
"displayName": "Measure Data",
"name": "measure",
"kind": "Measure"
删除 objects 键的所有内容(稍后再进行填写)。
删除其内容后,objects 键如下所示:
"objects": {},
将 dataViewMappings 属性替换为以下代码。 measure 中的 max: 1 指定只能将一个数据字段提交到视觉对象的“度量值数据”字段。
"dataViewMappings": [
"conditions": [
"measure": {
"max": 1
"single": {
"role": "measure"
保存对 capabilities.json 所做的更改。
验证 pbiviz start 是否正在运行,然后在 Power BI 服务中,刷新“React 圆形卡片”视觉对象。 “度量值数据”字段只能有一个数据字段,如 max: 1 所指定。
设置视觉对象以接收来自 Power BI 的属性
在本部分中,你将配置视觉对象以接收来自 Power BI 的数据,并将更新发送到 component.tsx 文件中的实例。
使用 React 呈现数据
可以使用 React 呈现数据。 组件可以显示来自其自身状态的数据。
在 VS Code 的 reactCircleCard 文件夹中,打开 component.tsx。
将 component.tsx 的内容替换为以下代码。
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">
{textLabel}
<em>{textValue}</em>
保存 component.tsx。
设置视觉对象以接收数据
视觉对象接收数据作为 update 方法的参数。 在本部分中,你将更新此方法以接收数据。
以下代码从 DataView 中选择 textLabel 和 textValue,如果数据存在,则更新组件状态。
在 VS Code 的 src 文件夹中,打开 visual.ts。
请使用以下代码替换 import ReactCircleCard from "./component"; 这一行:
import { ReactCircleCard, initialState } from "./component";
将以下代码添加到 update 方法中。
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();
通过在 update 方法后添加以下代码来创建 clear 方法。
private clear() {
ReactCircleCard.update(initialState);
保存 visual.ts
设置视觉对象以发送数据
在本部分中,你将更新视觉对象以将更新发送到 component 文件中的实例。
在 VS Code 的 src 文件夹中,打开 component.tsx。
将以下代码添加到 ReactCircleCard 类:
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;
保存 component.tsx。
查看对视觉对象所做的更改
测试“React 圆形卡片”视觉对象以查看所做的更改。
验证 pbiviz start 是否正在运行,然后在 Power BI 服务中,刷新“React 圆形卡片”视觉对象。
将“销售额”添加到视觉对象的“度量值数据”字段。
让视觉对象可调
目前,视觉对象具有固定的宽度和高度。 若要使视觉对象的大小可调整,需要在 visual.ts 和 component.tsx 文件中定义 size 变量 。 在本部分中,你将让视觉对象可调。
完成本部分中所述的步骤后,视觉对象中的圆形直径将与最小宽度或高度大小相对应,并且可以在 Power BI 服务中调整其大小。
从 options 对象获取视觉对象视区的当前大小。
在 VS Code 的 src 文件夹中,打开 visual.ts。
插入此代码以导入 IViewport 接口。
import IViewport = powerbi.IViewport;
将 viewport 属性添加到 visual 类。
private viewport: IViewport;
在 update 方法中,在 ReactCircleCard.update 之前添加以下代码。
this.viewport = options.viewport;
const { width, height } = this.viewport;
const size = Math.min(width, height);
在 update 方法中,在 ReactCircleCard.update 中添加 size。
size,
保存 visual.ts。
在 VS Code 的 src 文件夹中,打开 component.tsx。
将以下代码添加到 export interface State。
size: number
将以下代码添加到 export const initialState: State。
size: 200
在 render 方法中,执行以下操作:
已将 size 添加到 const { textLabel, textValue, size } = this.state;。 此声明现在应如下所示:
const { textLabel, textValue, size } = this.state;
将以下代码添加到 return 上方。
const style: React.CSSProperties = { width: size, height: size };
将第一个 return 行 <div className="circleCard"> 替换为:
<div className="circleCard" style={style}>
在 VS Code 的 style 文件夹中,打开 visual.less。
在 .circleCard 中,将 width 和 height 替换为 min-width 和 min-height。
min-width: 200px;
min-height: 200px;
保存 visual.less。
使 Power BI 视觉对象可自定义
在本部分中,你将添加自定义视觉对象的功能,允许用户更改其颜色和边框宽度。
向功能文件添加颜色和粗细
向 capabilities.json 中的 object 属性添加颜色和边框粗细。
在 VS Code 的 reactCircleCard 文件夹中,打开 capabilities.json。
将以下设置添加到 objects 属性。
"circle": {
"properties": {
"circleColor": {
"type": {
"fill": {
"solid": {
"color": true
"circleThickness": {
"type": {
"numeric": true
保存 capabilities.json。
将 Circle 格式化设置添加到 settings.ts。 若要详细了解如何生成格式设置模型设置,请参阅格式设置 utils。
在 VS Code 的 src 文件夹中,打开 settings.ts。
将 settings.ts 中的代码替换为以下代码:
"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<FormattingSettingsSlice> = [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];
保存 settings.ts。
添加方法以应用视觉对象设置
将用于应用视觉对象设置的 getFormattingModel 方法和所需的导入添加到 visuals.ts 文件。
在 VS Code 的 src 文件夹中,打开 visuals.ts。
将这些 import 语句添加到 visual.ts 的顶部。
import { FormattingSettingsService } from "powerbi-visuals-utils-formattingmodel";
import { VisualFormattingSettingsModel } from "./settings";
将以下声明添加到“视觉对象”。
private formattingSettings: VisualFormattingSettingsModel;
private formattingSettingsService: FormattingSettingsService;
将 getFormattingModel 方法添加到“视觉对象”。
public getFormattingModel(): powerbi.visuals.FormattingModel {
return this.formattingSettingsService.buildFormattingModel(this.formattingSettings);
在 Visual 类中,向 constructor 添加以下代码行以初始化 formattingSettingsService
this.formattingSettingsService = new FormattingSettingsService();
在 Visual 类中,向 update 添加以下代码,以将视觉对象格式化设置更新到最新的格式设置属性值。
将此代码添加到 const size = Math.min(width, height); 后面的 if 语句。
this.formattingSettings = this.formattingSettingsService.populateFormattingSettingsModel(VisualFormattingSettingsModel, options.dataViews);
const circleSettings = this.formattingSettings.circleCard;
将此代码添加到 size 之后的 ReactCircleCard.update 调用:
borderWidth: circleSettings.circleThickness.value,
background: circleSettings.circleColor.value.value,
const { textLabel, textValue, size } = this.state; 替换为:
const { textLabel, textValue, size, background, borderWidth } = this.state;
const style: React.CSSProperties = { width: size, height: size }; 替换为:
const style: React.CSSProperties = { width: size, height: size, background, borderWidth };