Power BI 시각적 개체 선택 항목별로 시각적 개체에 대화형 작업 추가

Power BI는 시각적 개체와 상호 작용하는 두 가지 방법(선택 및 필터링)을 제공합니다. 다음 예제에서는 한 시각적 개체에서 항목을 선택하고 보고서의 다른 시각적 개체에 새 선택 상태에 대해 알리는 방법을 보여 줍니다.

인터페이스는 Selection 개체에 해당합니다.

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

선택 관리자를 사용하여 데이터 요소 선택

시각적 호스트 개체는 선택 관리자의 인스턴스를 만드는 메서드를 제공합니다. 선택 관리자에는 다음 각 작업에 해당하는 메서드가 있습니다.

  • 선택
  • 선택 영역 지우기
  • 바로 가기 메뉴 표시
  • 현재 선택 영역 저장
  • 선택 상태 확인

선택 관리자의 인스턴스를 만듭니다.

선택 관리자를 사용하려면 선택 관리자의 인스턴스를 만듭니다. 일반적으로 시각적 개체는 시각적 개체의 constructor 섹션에서 선택 관리자 인스턴스를 만듭니다.

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

선택 작성기의 인스턴스를 만듭니다.

선택 관리자 인스턴스가 만들어지면 시각적 개체의 각 데이터 요소에 대해 selections를 만들어야 합니다. 시각적 호스트 개체의 createSelectionIdBuilder 메서드는 각 데이터 요소에 대한 선택 항목을 생성합니다. 이 메서드는 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를 만드는 해당 메서드가 있습니다.

참고 항목

withTablewithMatrixNode 메서드는 Power BI 시각적 개체의 API 2.5.0에서 도입되었습니다. 테이블 또는 행렬 데이터 뷰 매핑의 선택 항목을 사용해야 하는 경우 API 버전을 2.5.0 이상으로 업데이트해야 합니다.

범주 데이터 뷰 매핑에 대한 선택 항목 만들기

선택 항목이 샘플 의미 체계 모델에 대한 범주 데이터 보기 매핑을 나타내는 방법을 검토해 보겠습니다.

제조업체 Type
Chrysler 국내 승용차 28883
Chrysler 국내 트럭 117131
Chrysler 수입 승용차 0
Chrysler Import Truck 6362
Ford 국내 승용차 50032
Ford 국내 트럭 122446
Ford 수입 승용차 0
Ford Import Truck 0
GM 국내 승용차 65426
GM 국내 트럭 138122
GM 수입 승용차 197
GM Import Truck 0
Honda 국내 승용차 51450
Honda 국내 트럭 46115
Honda 수입 승용차 2932
Honda Import Truck 0
Nissan 국내 승용차 51476
Nissan 국내 트럭 47343
Nissan 수입 승용차 5485
Nissan Import Truck 1430
Toyota 국내 승용차 55643
Toyota 국내 트럭 61227
Toyota 수입 승용차 20799
Toyota Import Truck 23614

시각적 개체는 다음과 같은 데이터 뷰 매핑을 사용합니다.

{
    "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입니다. 계열은 값을 rows(Type)별로 그룹화하여 만듭니다.

시각적 개체는 Manufacturer 또는 Type을 기준으로 데이터를 분할할 수 있어야 합니다.

예를 들어 사용자가 ManufacturerChrysler를 선택하면 다른 시각적 개체에 다음 데이터가 표시되어야 합니다.

제조업체 Type
Chrysler 국내 승용차 28883
Chrysler 국내 트럭 117131
Chrysler 수입 승용차 0
Chrysler Import Truck 6362

사용자가 Type으로 Import Car를 선택하면(계열을 기준으로 데이터를 선택) 다른 시각적 개체는 다음 데이터를 표시해야 합니다.

제조업체 Type
Chrysler 수입 승용차 0
Ford 수입 승용차 0
GM 수입 승용차 197
Honda 수입 승용차 2932
Nissan 수입 승용차 5485
Toyota 수입 승용차 20799

선택 항목이 있는 시각적 개체를 보여 주는 스크린샷

조각화된 데이터를 표시하려면 다음과 같이 시각적 개체의 데이터 바구니를 채웁니다.

시각적 개체의 데이터 바구니를 보여 주는 스크린샷

앞의 예제에서 Manufacturer는 범주(열)이고 Type는 계열(행)이며 Sales는 계열의 Values입니다.

참고 항목

Values는 데이터 뷰 매핑에 따라 ValuesRows 데이터별로 그룹화되므로 계열을 표시하는 데 필요합니다.

범주에 대한 선택 항목 만들기

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

위의 샘플 코드에서는 모든 범주를 반복합니다. 각 반복에서 createSelectionIdBuilder를 호출하고 선택 항목 작성기의 withCategory 메서드를 호출하여 각 범주에 대해 다음 선택 항목을 만듭니다. createSelectionId 메서드는 생성된 selection 개체를 반환하는 최종 메서드로 사용됩니다.

withCategory 메서드에서는 category의 열을 전달하고, 샘플에서는 Manufacturer 및 범주 요소의 인덱스입니다.

계열에 대한 선택 항목 만들기

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

테이블 데이터 뷰 매핑에 대한 선택 항목 만들기

다음 예제에서는 테이블 데이터 뷰 매핑을 보여 줍니다.

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

테이블 데이터 뷰 매핑의 각 행에 대해 선택 항목을 만들려면 선택 항목 작성기의 withTable 메서드를 호출합니다.

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 테이블 메서드를 호출합니다. withTable 메서드의 매개 변수는 테이블 행의 table 개체 및 인덱스입니다.

행렬 데이터 뷰 매핑에 대한 선택 항목 만들기

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는 각 노드 및 자식 노드를 재귀적으로 호출합니다.

nodeWalker는 각 호출에서 nodeSelection 개체를 만듭니다. 각 nodeSelection은 해당 노드의 selection을 나타냅니다.

데이터 요소를 선택하여 다른 시각적 개체를 조각화

이 예제에서는 단추 요소에 대한 클릭 처리기를 만들었습니다. 이 처리기는 선택 항목 관리자의 select 메서드를 호출하고 선택 항목 개체를 전달합니다.

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

select 메서드의 인터페이스:

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

select 메서드는 선택 항목의 배열을 수락할 수 있습니다. 이렇게 하면 시각적 개체에서 한 번에 여러 데이터 포인트를 선택할 수 있습니다. 두 번째 매개 변수 multiSelect에서 다중 선택을 담당합니다. multiSelect가 true인 경우 Power BI는 현재 선택 영역을 적용할 때 이전 선택 상태를 지우지 않습니다. 값이 false이면 이전 선택을 덮어씁니다.

multiSelect를 사용하는 일반적인 예는 클릭 이벤트에서 Ctrl 단추 상태를 처리하는 것입니다. Ctrl 단추를 누른 상태에서 둘 이상의 개체를 선택할 수 있습니다.

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