Power BI 시각적 개체 선택 항목별로 시각적 개체에 대화형 작업 추가Add interactivity into visual by Power BI visuals selections

Power BI는 시각적 개체 사이의 두 가지 상호 작용 방법인 선택 및 필터링 기능을 제공합니다.Power BI provides two ways of interaction between visuals - selection and filtering. 아래 샘플에서는 한 시각적 개체의 항목을 선택하고 보고서의 다른 시각적 개체에 새 선택 상태를 알리는 방법을 보여줍니다.The sample below demonstrates how to select any items in one visual and notify other visuals in the report about new selection state.

Selection 개체는 인터페이스에 해당합니다.Selection object corresponds to the interface:

export interface ISelectionId {
    equals(other: ISelectionId): boolean;
    includes(other: ISelectionId, ignoreHighlight?: boolean): boolean;
    getKey(): string;
    getSelector(): Selector;
    getSelectorsByColumn(): SelectorsByColumn;
    hasIdentity(): boolean;
}

SelectionManager를 사용하여 데이터 요소를 선택하는 방법How to use SelectionManager to select data points

시각적 호스트 개체는 선택 관리자 인스턴스를 만드는 메서드를 제공합니다.The visual host object provides the method for creating an instance of selection manager. 선택 관리자는 선택 항목 선택 및 선택 취소, 상황에 맞는 메뉴 표시, 현재 선택 항목 저장 및 선택 상태 확인을 담당합니다.The selection manager responsible to select, to clear selection, to show the context menu, to store current selections and check selection state. 또한 선택 관리자에는 이 작업에 해당하는 메서드가 있습니다.And the selection manager has corresponded methods for those actions.

선택 관리자의 인스턴스를 만듭니다.Create an instance of the selection manager

선택 관리자를 사용하려면 선택 관리자 인스턴스를 만들어야 합니다.For using the selection manager, you need to create the instance of a selection manager. 일반적으로 시각적 개체는 시각적 개체의 constructor에서 선택 관리자 인스턴스를 만듭니다.Usually, visuals create a selection manager instance in the constructor of the visual object.

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();
    }
    // ...
}

선택 작성기의 인스턴스를 만듭니다.Create an instance of the selection builder

선택 관리자 인스턴스가 만들어지면 시각적 개체의 각 데이터 요소에 대해 selections를 만들어야 합니다.When the selection manager instance is created, you need to create selections for each data point of the visual. 시각적 호스트 개체는 각 데이터 요소에 대해 선택 항목을 생성하는 createSelectionIdBuilder 메서드를 제공합니다.The visual host object provides createSelectionIdBuilder method to generate selection for each data point. 이 메서드는 powerbi.visuals.ISelectionIdBuilder 인터페이스를 사용하여 개체의 인스턴스를 반환합니다.This method return instance of the object with interface powerbi.visuals.ISelectionIdBuilder:

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를 만들 수 있는 메서드가 있습니다.This object has corresponded methods to create selections for different types of data view mappings.

참고

withTablewithMatrixNode 메서드는 Power BI 시각적 개체의 API 2.5.0에서 도입되었습니다.The methods withTable and withMatrixNode were introduced on API 2.5.0 of the Power BI visuals. 테이블 또는 행렬 데이터 뷰 매핑의 선택 항목을 사용해야 하는 경우 API 버전을 2.5.0 이상으로 업데이트해야 합니다.If you need to use selections for table or matrix data view mappings you need to update API version to 2.5.0 or higher.

범주 데이터 뷰 매핑에 대한 선택 항목 만들기Create selections for categorical data view mapping

샘플 데이터 세트에 대한 범주 데이터 뷰 매핑에서 선택 항목이 어떻게 표시되는지 검토해 보겠습니다.Let's review how selections represent on categorical data view mapping for sample dataset:

제조업체Manufacturer 형식Type Value
ChryslerChrysler 국내 승용차Domestic Car 2888328883
ChryslerChrysler 국내 트럭Domestic Truck 117131117131
ChryslerChrysler 수입 승용차Import Car 00
ChryslerChrysler 수입 트럭Import Truck 63626362
FordFord 국내 승용차Domestic Car 5003250032
FordFord 국내 트럭Domestic Truck 122446122446
FordFord 수입 승용차Import Car 00
FordFord 수입 트럭Import Truck 00
GMGM 국내 승용차Domestic Car 6542665426
GMGM 국내 트럭Domestic Truck 138122138122
GMGM 수입 승용차Import Car 197197
GMGM 수입 트럭Import Truck 00
HondaHonda 국내 승용차Domestic Car 5145051450
HondaHonda 국내 트럭Domestic Truck 4611546115
HondaHonda 수입 승용차Import Car 29322932
HondaHonda 수입 트럭Import Truck 00
NissanNissan 국내 승용차Domestic Car 5147651476
NissanNissan 국내 트럭Domestic Truck 4734347343
NissanNissan 수입 승용차Import Car 54855485
NissanNissan 수입 트럭Import Truck 14301430
ToyotaToyota 국내 승용차Domestic Car 5564355643
ToyotaToyota 국내 트럭Domestic Truck 6122761227
ToyotaToyota 수입 승용차Import Car 2079920799
ToyotaToyota 수입 트럭Import Truck 2361423614

시각적 개체는 다음과 같은 데이터 뷰 매핑을 사용합니다.And the visual uses the following data view mapping:

{
    "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"
                                }
                            }
                        ]
                    }
                }
            }
        }
    ]
}

이 샘플에서는 Manufacturercolumns이고 Typerows입니다.In the sample, Manufacturer is columns and Type is rows. rows(Type)를 기준으로 값을 그룹화하여 만든 시리즈가 있습니다.There's series created by groupings values by rows (Type).

그리고 시각적 개체는 ManufacturerType을 기준으로 데이터를 분할할 수 있어야 합니다.And visual should able to slice data by Manufacturer and Type too.

예를 들어 사용자가 Manufacturer에서 Chrysler를 선택하면 다른 시각적 개체는 다음 데이터를 표시해야 합니다.For example, when user selects Chrysler by Manufacturer, other visuals should show following data:

제조업체Manufacturer 형식Type Value
ChryslerChrysler 국내 승용차Domestic Car 2888328883
ChryslerChrysler 국내 트럭Domestic Truck 117131117131
ChryslerChrysler 수입 승용차Import Car 00
ChryslerChrysler 수입 트럭Import Truck 63626362

사용자가 Type에서 Import Car를 선택하면(계열을 기준으로 데이터를 선택) 다른 시각적 개체는 다음 데이터를 표시해야 합니다.When user selects Import Car by Type (selects data by series), other visuals should show following data:

제조업체Manufacturer 형식Type Value
ChryslerChrysler 수입 승용차Import Car 00
FordFord 수입 승용차Import Car 00
GMGM 수입 승용차Import Car 197197
HondaHonda 수입 승용차Import Car 29322932
NissanNissan 수입 승용차Import Car 54855485
ToyotaToyota 수입 승용차Import Car 2079920799

범주 및 계열에 대한 선택 항목이 포함된 시각적 개체

시각적 데이터 바구니를 채워야 합니다.Need to fill the visual data baskets.

선택 항목이 포함된 시각적 개체의 데이터 바구니

범주(열)로 Manufacturer, 계열(행)로 Type, 계열에 대한 ValuesValue가 있습니다.There are Manufacturer as category (columns), Type as series (rows) and Value as Values for series.

참고

시각적 개체는 데이터 뷰 매핑에 따라 ValuesRows 데이터를 기준으로 그룹화될 것으로 예상하므로 Values가 계열에 필요합니다.The Values are required for series because according to data view mapping the visual expects that Values will be grouped by Rows data.

범주에 대한 선택 항목 만들기Create selections for categories

// categories
const categories = dataView.categorical.categories;

// create label for 'Manufacturer' column
const p = document.createElement("p") as HTMLParagraphElement;
p.innerText = categories[0].source.displayName.toString();
this.target.appendChild(p);

// get count of category elements
const categoriesCount = categories[0].values.length;

// iterate all categories to generate selection and create button elements to use selections
for (let categoryIndex = 0; categoryIndex < categoriesCount; 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);
}

샘플 코드에서는 모든 범주를 반복하는 것을 볼 수 있습니다.In the sample code, you can see that we iterate all categories. 또한 각 반복에서 createSelectionIdBuilder를 호출하고 선택 항목 작성기의 withCategory 메서드를 호출하여 각 범주에 대해 다음 선택 항목을 만듭니다.And in each iteration, we call createSelectionIdBuilder to create the next selection for each category by calling withCategory method of the selection builder. createSelectionId 메서드는 생성된 selection 개체를 반환하는 최종 메서드로 사용됩니다.The method createSelectionId is used as a final method to return the generated selection object.

withCategory 메서드에서는 category의 열을 전달하고, 샘플에서는 이것이 Manufacturer와 범주 요소의 인덱스입니다.In withCategory method, we pass the column of category, in the sample, it's Manufacturer and index of category element.

계열에 대한 선택 항목 만들기Create selections for series

// get groupped values for series
const series: powerbi.DataViewValueColumnGroup[] = dataView.categorical.values.grouped();

// create label for 'Type' column
const 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 selections
series.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);
});

테이블 데이터 뷰 매핑에 대한 선택 항목 만들기Create selections for table data view mapping

테이블 데이터 뷰 매핑 샘플Sample of table data views mapping

{
    "dataRoles": [
        {
            "displayName": "Values",
            "name": "values",
            "kind": "GroupingOrMeasure"
        }
    ],
    "dataViewMappings": [
        {
            "table": {
                "rows": {
                    "for": {
                        "in": "values"
                    }
                }
            }
        }
    ]
}

테이블 데이터 뷰 매핑의 각 행에 대해 선택 항목을 만들려면 선택 항목 작성기의 withTable 메서드를 호출해야 합니다.To create a selection for each row of table data view mapping, you need to call withTable method of selection builder.

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 테이블 메서드를 호출합니다.The visual code iterates the rows of the table and each row calls withTable table method. withTable 메서드의 매개 변수는 테이블 행의 table 개체 및 인덱스입니다.Parameters of withTable method are table object and index of the table row.

행렬 데이터 뷰 매핑에 대한 선택 항목 만들기Create selections for matrix data view mapping

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는 각 노드 및 자식 노드에 대해 재귀적으로 호출합니다.In the sample, nodeWalker calls recursively for each node and child nodes.

nodeWalker는 각 호출에서 nodeSelection 개체를 만듭니다.nodeWalker creates nodeSelection object on each call. 그리고 각 nodeSelection은 해당 노드의 selection을 나타냅니다.And each nodeSelection represent selection of correspond nodes.

데이터 요소를 선택하여 다른 시각적 개체를 조각화Select datapoints to slice other visuals

범주 데이터 뷰 매핑 선택 항목의 샘플 코드에서 단추 요소에 대한 클릭 처리기를 만들었습니다.In the sample, codes of selections for categorical data view mapping, you saw that we created a click handler for button elements. 이 처리기는 선택 항목 관리자의 select 메서드를 호출하고 선택 항목 개체를 전달합니다.The handler calls select method of the selection manager and passes the selection object.

button.addEventListener("click", () => {
    // handle click event to apply correspond selection
    this.selectionManager.select(categorySelectionId);
});

select 메서드의 인터페이스는The interface of select method is

interface ISelectionManager {
    // ...
    select(selectionId: ISelectionId | ISelectionId[], multiSelect?: boolean): IPromise<ISelectionId[]>;
    // ...
}

select는 선택 항목의 배열을 수락할 수 있다는 것을 알 수 있습니다.You can see select can accept an array of selections. 이는 시각적 개체가 여러 데이터 요소를 선택할 수 있음을 의미합니다.It means your visual can select several datapoints. 두 번째 매개 변수 multiSelect에서 다중 선택을 담당합니다.The second parameter multiSelect responsible for multi-select. 값이 true이면 Power BI가 이전 선택 상태를 지우지 않고 현재 선택을 적용합니다. 그렇지 않으면 이전 선택 항목이 다시 설정됩니다.If the value is true, Power BI doesn't clear the previous selection state and apply current selection otherwise previous selection will reset.

클릭 이벤트에서 CTRL 단추 상태를 처리하는 multiSelect를 사용하는 일반적인 시나리오입니다.The typical scenario of using multiSelect handling CTRL button state on click event.

button.addEventListener("click", (mouseEvent) => {
    const multiSelect = (mouseEvent as MouseEvent).ctrlKey;
    this.selectionManager.select(seriesSelectionId, multiSelect);
});

다음 단계Next steps