다음을 통해 공유


Power BI 시각적 개체의 대화 상자 만들기

시각적 개체를 만들 때 고객에게 별도 창에 추가 정보를 표시하면 유용한 경우가 있습니다. 예를 들어, 다음을 수행합니다.

  • 추가 정보 표시 - 텍스트 메모, 동영상 등
  • 입력 데이터 대화 상자 표시 - 날짜 대화 상자 등

이러한 목적을 위해 이 문서에서는 대화 상자라는 대화 상자 시각적 팝업 창을 만들 수 있습니다.

대화 상자 고려 사항

시각적 개체에 대한 대화 상자를 만들 때는 다음 사항에 유의하세요.

  • 개발 중에 대화 상자의 크기와 위치를 지정할 수 있습니다.
  • 대화 상자가 트리거되면 보고서 배경이 회색으로 표시됩니다.
  • 대화 머리글에는 시각적 개체의 아이콘과 표시 이름이 제목으로 포함됩니다.
  • 대화 상자에는 최대 3개의 작업 단추가 있을 수 있습니다. 지정된 선택 항목에서 표시할 단추를 선택할 수 있습니다.
  • 대화 상자는 서식 있는 HTML iframe을 사용합니다.
  • 대화 상자가 표시되면 해제될 때까지 보고서에서 아무 작업도 수행할 수 없습니다.
  • 대화 코드에서는 시각적 개체와 마찬가지로 외부 NPM 라이브러리를 사용할 수 있습니다.

Important

대화 상자는 자동으로 트리거되지 않아야 합니다. 사용자 작업의 즉각적인 결과여야 합니다.

시각적 개체의 대화 상자 디자인

대화 상자를 구성하려면 코드에 다음 두 가지 구성 요소를 추가해야 합니다.

대화 상자 구현 파일 만들기

만드는 각 대화 상자의 구현 파일을 만드는 것이 좋습니다. 대화 상자 파일을 src 폴더에 저장합니다.

Power BI 시각적 개체 프로젝트에서 DatePickerDialog.ts라는 대화 상자 구현 파일의 위치를 보여 주는 스크린샷

각 대화 상자 구현 파일에는 다음 구성 요소가 포함되어야 합니다.

대화 상자 클래스 만들기

대화 상자의 대화 상자 클래스를 만듭니다. 대화 상자를 만들 때 대화 상자 계약자에게 openModalDialoginitialState 매개 변수가 전달됩니다. 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 이상에서 openModalDialogDialogOpenOptions 매개 변수를 사용하여 대화 상자의 크기와 위치를 정의할 수 있습니다. 사용 중인 버전을 확인하려면 pbiviz.json 파일에서 apiVersion을 확인합니다.

    export interface RectSize {
        width: number;
        height: number;
    }

    export interface DialogOpenOptions {
        title: string;
        size?: RectSize;
        position?: VisualDialogPosition;
        actionButtons: DialogAction[];
    }

위치 매개 변수를 사용하면 대화 상자가 화면에서 열리는 위치를 결정할 수 있습니다. 화면 가운데에서 대화 상자를 열거나 시각적 개체를 기준으로 다른 위치를 정의할 수 있습니다.

    const enum VisualDialogPositionType {
        Center = 0,
        RelativeToVisual = 1
    }

    export interface VisualDialogPosition {
        type: VisualDialogPositionType;
        left?: number;
        top?: number;
    }
  • 형식이 지정되지 않은 경우 기본값은 가운데서 대화 상자를 여는 것입니다.
  • 위치는 시각적 개체의 왼쪽 위 모서리를 기준으로 픽셀 단위로 지정됩니다.

이 예제에서는 시각적 개체 위쪽에서 왼쪽으로 100픽셀, 아래쪽으로 30픽셀인 위치에 250x300픽셀 날짜 선택 대화 상자를 표시합니다.

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 닫기 메서드를 호출하여 대화 상자가 자동으로 닫히도록 프로그래밍할 수도 있습니다. 이 메서드는 대화 상자가 열린 후 5초 동안 차단되므로 대화 상자를 자동으로 닫을 수 있는 가장 빠른 시간은 대화 상자가 시작되고 5초 후입니다.

대화 상자 표시 안 함

사용자에게 대화 상자를 차단할 수 있는 옵션을 제공하는 확인란과 함께 대화 상자가 나타납니다.

대화 상자를 차단하는 옵션을 제공하는 확인란을 보여주는 스크린샷.

이 확인란은 시각적 개체가 사용자의 동의 없이(의도적이든 아니든) 모달 대화 상자를 만들지 못하게 하는 보안 기능입니다.

이 차단은 현재 세션에만 적용됩니다. 따라서 사용자가 CV 모달 대화를 차단하지만, 나중에 마음이 바뀌면 대화를 다시 사용하도록 설정할 수 있습니다. 이렇게 하려면 새 세션을 시작해야 합니다(Power BI 서비스 보고서 페이지를 새로 고치거나 Power BI Desktop을 다시 시작).

고려 사항 및 제한 사항

  • powerbi-visuals-API 3.8부터 대화 상자 아이콘과 제목은 시각적 개체의 아이콘 및 표시 이름에 따라 결정되며 변경할 수 없습니다.

  • 대화 상자의 크기 제한은 아래 표에 설명되어 있습니다.

    최대/최소 너비 높이
    최댓값 브라우저 너비의 90% 브라우저 높이의 90%
    최소 240 px 210px
  • 대화 상자의 위치를 정의할 때 가로 위치는 시각적 개체의 어느 쪽에 상자를 배치하려는 지에 따라 양수 또는 음수일 수 있습니다. 음수는 시각적 개체 위에 배치하므로 세로 위치는 음수일 수 없습니다.

  • 다음 기능에서는 Power BI 시각적 개체 대화 상자를 지원하지 않습니다.

    • 임베디드 분석
    • 웹에 게시
    • 대시보드

this.host.hostCapabilities.allowModalDialog 부울을 확인하여 현재 환경에서 대화 상자를 열 수 있는지 검색하도록 시각적 개체를 프로그래밍할 수 있습니다.