다음을 통해 공유


개체 기반 서식 지정 API(미리 보기)

개체 기반 서식 지정을 사용하면 사용자가 수정하려는 요소를 직접 선택하여 시각적 개체 서식을 빠르고 쉽게 수정할 수 있습니다. 요소를 선택하면 서식 창에서 선택한 요소에 대한 특정 서식 설정을 자동으로 탐색하고 확장합니다. 개체 기반 서식 지정에 대한 자세한 내용은 Power BI Desktop의 개체 기반 서식 지정을 참조하세요.

시각적 개체에 이러한 기능을 추가하려면 각 시각적 개체가 하위 선택 가능한 각 영역에 대한 하위 선택 스타일 옵션과 바로 가기를 제공해야 합니다.

참고 항목

  • 개체 기반 서식 지정을 지원하는 시각적 개체는 API 버전 5.1에서 사용할 수 있는 getFormattingModel API를 구현해야 합니다.
  • powerbi-visuals-utils-formattingmodel을 사용하는 경우 버전 6.0.0 이상을 사용합니다.

개체 기반 환경 만들기

사용자가 하위 선택 가능한 요소를 선택하여 Power BI에 하위 선택을 보낼 때 하위 선택 서비스를 사용합니다. 하위 선택 API를 사용하여 하위 선택 스타일과 바로 가기를 제공합니다. 하위 선택 도우미를 사용하면 프로세스를 간소화할 수 있습니다.

서식 모드

서식 모드는 사용자가 작성 모드에서 onObject 서식을 켜거나 끌 수 있는 새로운 모드입니다. 시각적 개체는 업데이트 옵션의 형식 모드 상태로 업데이트됩니다. 업데이트 옵션에는 현재 하위 선택된 subSelection도 CustomVisualSubSelection으로 포함됩니다.

개체 기반 서식 지정 API를 구현하는 방법

기능 파일

capabilites.json 파일에서 다음 속성을 추가하여 시각적 개체가 개체 기반 서식을 지원함을 선언합니다.

{
  "supportsOnObjectFormatting": true,
  "enablePointerEventsFormatMode": true,
}

IVVisual 인터페이스

시각적 개체는 IVisual 인터페이스의 일부로 VisualOnObjectFormatting 인터페이스를 구현해야 합니다.

VisualOnObjectFormatting에는 세 가지 메서드가 포함되어 있습니다.

getSubSelectionStyles

각 시각적 개체는 하위 선택 가능한 요소가 하위 선택될 때 호출되는 getSubSelectionStyles 메서드를 구현해야 합니다. getSubSelectionStyles 메서드는 현재 하위 선택된 요소와 함께 CustomVisualSubSelection 배열로 제공되며 SubSelectionStyles 개체 또는 undefined를 반환할 것으로 예상됩니다.

대부분의 시나리오를 다루는 하위 선택 스타일에는 세 가지 범주가 있습니다.

  • Text
  • 숫자 텍스트
  • 도형

SubSelectionStyles 개체는 사용자에게 요소 스타일 수정에 대한 다양한 환경을 제공합니다.

getSubSelectionShortcuts

사용자에게 더 많은 옵션을 제공하려면 시각적 개체가 getSubSelectionShortcuts 메서드를 구현해야 합니다. 이 메서드는 VisualSubSelectionShortcuts 또는 undefined를 반환합니다. 또한 SubSelectionShortcuts가 제공되면 사용자가 요소를 하위 선택하고 형식 창이 열릴 때 창이 자동으로 해당 카드로 스크롤되도록 VisualNavigateSubSelectionShortcut도 제공해야 합니다.

시각적 상태를 수정하기 위한 여러 하위 선택 바로 가기가 있습니다. 각각은 적절한 레이블을 사용하여 바로 가기 메뉴의 메뉴 항목을 정의합니다.

하위 선택 명확성 메뉴: 개체 명확성 메뉴는 어떤 시각적 개체가 하위 선택되고 있는지 확실하지 않을 때 사용자가 원하는 하위 선택을 선택할 수 있는 메서드를 제공합니다. 이는 사용자가 시각적 개체의 백그라운드를 하위 선택할 때 자주 발생합니다. 명확한 메뉴가 더 많은 하위 선택을 표시하려면 시각적 개체가 getSubSelectables 메서드를 통해 모든 하위 선택을 제공해야 합니다.

getSubSelectables

명확성 메뉴에 하위 선택을 제공하려면 시각적 개체가 getSubSelectables 메서드를 구현해야 합니다. 이 메서드에는 SubSelectionStylesType 형식의 선택적 filterType 인수가 제공되며 CustomVisualSubSelection 또는 undefined 배열을 반환합니다. 하위 선택을 만드는 데 HTMLSubSelectionHelper를 사용하는 경우 HTMLSubSelectionHelper.getSubSelectables() 메서드를 사용하여 DOM에서 하위 선택 가능한 요소를 수집할 수 있습니다.

하위 선택 직접 텍스트 편집: 개체 기반 서식을 사용하면 하위 선택 가능한 요소의 텍스트를 두 번 클릭하여 직접 편집할 수 있습니다. 직접 편집 기능을 제공하려면 SubSelectableDirectEdit 개체로 채워진 적절한 cVDirectEdit 속성과 함께 RectangleSubSelectionOutline을 제공해야 합니다. 개요는 사용자 지정 개요로 제공되거나 HTMLSubSelectionHelper를 사용하는 경우 SubSelectableDirectEdit 특성을 사용할 수 있습니다. (HTMLSubSelectionHelper에서 제공하는 특성 참조)

특정 데이터 포인트에 대한 직접 편집 추가(선택기 사용)는 아직 지원되지 않습니다.

FormattingId 인터페이스

다음 인터페이스는 subSelection 바로 가기 및 스타일을 참조하는 데 사용됩니다.

interface FormattingId {
            objectName: string;
            propertyName: string;
            selector?: powerbi.data.Selector;
        }
  • objectName:capabilities.json에 선언된 개체 이름입니다.
  • propertyName: capabilities.json에 선언된 개체의 속성 이름입니다.
  • selector: 데이터 포인트에 SelectionId가 있는 경우 SelectionId.getSelector()를 사용합니다. 이 선택기는 서식 지정 모델 조각에 제공된 것과 동일해야 합니다.

예제

이 예에서는 colorSelectordirectEdit라는 두 개체가 있는 사용자 지정 시각적 개체를 빌드합니다. 대부분의 subSelection 작업을 처리하기 위해 onobjectFormatting 유틸리티의 HTMLSubSelectionHelper를 사용합니다. 자세한 내용은 개체 기반 유틸리티를 참조하세요.

먼저 서식 지정 창용 카드를 만들고 각 하위 선택 가능 항목에 대해 subSelectionShortcutsstyles를 제공합니다.

개체 정의

개체를 정의하고 시각적 개체가 capabilities.json에서 OnObject 서식을 지원한다고 선언합니다.

"objects": {
      "directEdit": {
      "properties": {
        "show": {
          "displayName": "Show",
          "type": {
            "bool": true
          }
        },
        "textProperty": {
          "displayName": "Text",
          "type": {
            "text": true
          }
        },
        "fontFamily": {
          "type": {
            "formatting": {
              "fontFamily": true
            }
          }
        },
        "fontSize": {
          "type": {
            "formatting": {
              "fontSize": true
            }
          }
        },
        "bold": {
          "type": {
            "bool": true
          }
        },
        "italic": {
          "type": {
            "bool": true
          }
        },
        "underline": {
          "type": {
            "bool": true
          }
        },
        "fontColor": {
          "displayName": "Font Color",
          "type": {
            "fill": {
              "solid": {
                "color": true
              }
            }
          }
        },
        "background": {
          "displayName": "Background",
          "type": {
            "fill": {
              "solid": {
                "color": true
              }
            }
          }
        },
        "position": {
          "displayName": "Position",
          "type": {
            "enumeration": [
              { "displayName": "Left", "value": "Left" }, { "displayName": "Right", "value": "Right" }
            ]
          }
        }
      }
    },
    "colorSelector": {
      "displayName": "Data Colors",
      "properties": {
        "fill": {
          "displayName": "Color",
          "type": {
            "fill": {
              "solid": {
                "color": true
              }
            }
          }
        }
      }
    },
   },
  "supportsOnObjectFormatting": true,
  "enablePointerEventsFormatMode": true,

서식 카드 만들기

formattingModel 유틸리티를 사용하여 서식 지정 카드를 만듭니다.

색 선택기 카드 설정

class ColorSelectorCardSettings extends Card {
    name: string = "colorSelector";
    displayName: string = "Data Colors";
    slices = [];
}

colorSelector 개체(데이터 포인트)에 대한 조각을 동적으로 채울 수 있도록 formatingSetting에 메서드를 추가합니다.

populateColorSelector(dataPoints: BarChartDataPoint[]) {
        let slices: formattingSettings.ColorPicker[] = this.colorSelector.slices;
        if (dataPoints) {
            dataPoints.forEach(dataPoint => {
                slices.push(new formattingSettings.ColorPicker({
                    name: "fill",
                    displayName: dataPoint.category,
                    value: { value: dataPoint.color },
                    selector: dataPoint.selectionId.getSelector(),
                }));
            });
        }
    }

선택기 필드에 특정 데이터 포인트의 선택기를 전달합니다. 이 선택기는 OnObject의 가져오기 API를 구현할 때 사용되는 선택기입니다.

직접 편집 카드 설정

class DirectEditSettings extends Card {
    displayName = 'Direct Edit';
    name = 'directEdit';
    private minFontSize: number = 8;
    private defaultFontSize: number = 11;
    show = new formattingSettings.ToggleSwitch({
        name: "show",
        displayName: undefined,
        value: true,
    });
    topLevelSlice = this.show;
    textProperty = new formattingSettings.TextInput({
        displayName: "Text Property",
        name: "textProperty",
        value: "What is your quest?",
        placeholder: ""
    });
    position = new formattingSettings.ItemDropdown({
        name: 'position',
        items: [{ displayName: 'Left', value: 'Left' }, { displayName: 'Right', value: 'Right' }],
        value: { displayName: 'Right', value: 'Right' }
    });
    font = new formattingSettings.FontControl({
        name: "font",
        displayName: 'Font',
        fontFamily: new formattingSettings.FontPicker({
            name: "fontFamily",
            displayName: "Font Family",
            value: "Segoe UI, wf_segoe-ui_normal, helvetica, arial, sans-serif"
        }),
        fontSize: new formattingSettings.NumUpDown({
            name: "fontSize",
            displayName: "Font Size",
            value: this.defaultFontSize,
            options: {
                minValue: {
                    type: powerbi.visuals.ValidatorType.Min,
                    value: this.minFontSize,
                }
            }
        }),
        bold: new formattingSettings.ToggleSwitch({
            name: 'bold',
            displayName: "Font Size",
            value: true
        }),
        italic: new formattingSettings.ToggleSwitch({
            name: 'italic',
            displayName: "Font Size",
            value: true
        }),
        underline: new formattingSettings.ToggleSwitch({
            name: 'underline',
            displayName: "Font Size",
            value: true
        })
    });
    fontColor = new formattingSettings.ColorPicker({
        name: "fontColor",
        displayName: "Color",
        value: { value: "#000000" }
    });
    background = new formattingSettings.ColorPicker({
        name: "background",
        displayName: "Color",
        value: { value: "#FFFFFF" }
    });
    slices = [this.show, this.textProperty, this.font, this.fontColor, this.background, this.position];
}

하위 선택 도우미 특성 사용

개체에 HTMLSubSelectionHelper 특성을 추가합니다. HTMLSubSelectionHelper가 제공하는 특성을 보려면 개체 유틸리티 설명서를 확인합니다.

  • directEdit 특성의 경우:

    import {
       HtmlSubSelectableClass, HtmlSubSelectionHelper, SubSelectableDirectEdit as SubSelectableDirectEditAttr,
       SubSelectableDisplayNameAttribute, SubSelectableObjectNameAttribute, SubSelectableTypeAttribute 
    } from 'powerbi-visuals-utils-onobjectutils';
    
    const DirectEdit: powerbi.visuals.SubSelectableDirectEdit = {
        reference: {
            objectName: 'directEdit',
            propertyName: 'textProperty'
        },
        style: SubSelectableDirectEditStyle.Outline,
    };
    private visualDirectEditSubSelection = JSON.stringify(DirectEdit);
    
    this.directEditElement
                .classed('direct-edit', true)
                .classed('hidden', !this.formattingSettings.directEditSettings.show.value)
                .classed(HtmlSubSelectableClass, options.formatMode && this.formattingSettings.directEditSettings.show.value)
                .attr(SubSelectableObjectNameAttribute, 'directEdit')
                .attr(SubSelectableDisplayNameAttribute, 'Direct Edit')
                .attr(SubSelectableDirectEditAttr, this.visualDirectEditSubSelection)
    

    HTMLSubSelectionHelperSubSelectableDirectEditAttr 특성을 사용하여 directEdit 개요의 directEdit 참조를 제공하므로 사용자가 요소를 두 번 클릭하면 직접 편집이 시작됩니다.

    하위 선택 도우미의 작동 방식을 보여 주는 스크린샷.

  • colorSelector의 경우:

    barSelectionMerged
              .attr(SubSelectableObjectNameAttribute, 'colorSelector')
              .attr(SubSelectableDisplayNameAttribute, (dataPoint: BarChartDataPoint) => this.formattingSettings.colorSelector.slices[dataPoint.index].displayName)
              .attr(SubSelectableTypeAttribute, powerbi.visuals.SubSelectionStylesType.Shape)
              .classed(HtmlSubSelectableClass, options.formatMode)
    
    

참조 정의

예를 간소화하려면 다음 인터페이스를 정의합니다.

참고 항목

제공하는 cardUid는 getFormattingModel API에 제공된 것과 동일해야 합니다. 예를 들어, powerbi-visuals-utils-formattingmodel을 사용하는 경우 cardUidVisual-cardName-card로 제공합니다. 여기서 cardName은 서식 지정 모델 설정에서 이 카드에 할당한 이름입니다. 그렇지 않으면 이 카드에 할당한 Visual-cardUid로 제공합니다.

interface References {
    cardUid?: string;
    groupUid?: string;
    fill?: FormattingId;
    font?: FormattingId;
    fontColor?: FormattingId;
    show?: FormattingId;
    fontFamily?: FormattingId;
    bold?: FormattingId;
    italic?: FormattingId;
    underline?: FormattingId;
    fontSize?: FormattingId;
    position?: FormattingId;
    textProperty?: FormattingId;
}

이 예의 목적을 위해 개체 이름에 대한 열거형을 만듭니다.

const enum BarChartObjectNames {
    ColorSelector = 'colorSelector',
    DirectEdit = 'directEdit'
}
  • directEdit 개체에 대한 참조:
const directEditReferences: References = {
    cardUid: 'Visual-directEdit-card',
    groupUid: 'directEdit-group',
    fontFamily: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'fontFamily'
    },
    bold: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'bold'
    },
    italic: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'italic'
    },
    underline: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'underline'
    },
    fontSize: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'fontSize'
    },
    fontColor: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'fontColor'
    },
    show: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'show'
    },
    position: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'position'
    },
    textProperty: {
        objectName: BarChartObjectNames.DirectEdit,
        propertyName: 'textProperty'
    }
};
  • colorSelector의 경우:
const colorSelectorReferences: References = {
    cardUid: 'Visual-colorSelector-card',
    groupUid: 'colorSelector-group',
    fill: {
        objectName: BarChartObjectNames.ColorSelector,
        propertyName: 'fill'
    }
};

API 구현

이제 onObject 서식에 대한 가져오기 API를 구현하고 이를 VisualOnObjectFormatting에 제공해 보겠습니다.

  1. 생성자 코드에서 VisualOnObjectFormatting에 get 메서드를 제공합니다.

    public visualOnObjectFormatting: powerbi.extensibility.visual.VisualOnObjectFormatting;
    constructor(options: VisualConstructorOptions) {
            this.subSelectionHelper = HtmlSubSelectionHelper.createHtmlSubselectionHelper({
                     hostElement: options.element,
                     subSelectionService: options.host.subSelectionService,
                     selectionIdCallback: (e) => this.selectionIdCallback(e),
                });
    
     this.visualOnObjectFormatting = {
                    getSubSelectionStyles: (subSelections) => this.getSubSelectionStyles(subSelections),
                    getSubSelectionShortcuts: (subSelections, filter) => this.getSubSelectionShortcuts(subSelections, filter),
                    getSubSelectables: (filter) => this. getSubSelectables(filter)
                }
       }
    
    private getSubSelectionStyles(subSelections: CustomVisualSubSelection[]): powerbi.visuals.SubSelectionStyles | undefined {
            const visualObject = subSelections[0]?.customVisualObjects[0];
            if (visualObject) {
                switch (visualObject.objectName) {
                    case BarChartObjectNames.ColorSelector:
                        return this.getColorSelectorStyles(subSelections);
                     case BarChartObjectNames.DirectEdit:
                        return this.getDirectEditStyles();
                }
            }
        }
    
    private getSubSelectionShortcuts(subSelections: CustomVisualSubSelection[], filter: SubSelectionShortcutsKey | undefined):    VisualSubSelectionShortcuts | undefined {
            const visualObject = subSelections[0]?.  customVisualObjects[0];
            if (visualObject) {
                switch (visualObject.objectName) {
                    case BarChartObjectNames.ColorSelector:
                        return this.getColorSelectorShortcuts(subSelections);
                    case BarChartObjectNames.DirectEdit:
                        return this.getDirectEditShortcuts();
                }
            }
        }
    
  2. colorSelector에 대한 getSubSelection 바로 가기 및 스타일을 구현합니다.

    private getColorSelectorShortcuts(subSelections:  CustomVisualSubSelection[]): VisualSubSelectionShortcuts   {
            const selector = subSelections[0].customVisualObjects[0].selectionId?.getSelector();
            return [
                {
                    type: VisualShortcutType.Reset,
                    relatedResetFormattingIds: [{
                        ...colorSelectorReferences.fill,
                        selector
                    }],
                },
                {
                    type: VisualShortcutType.Navigate,
                    destinationInfo: { cardUid: colorSelectorReferences.cardUid },
                    label: 'Color'
                }
            ];
        }
    

    위 바로 가기는 바로 가기 메뉴에 관련 메뉴 항목을 반환하고 다음 기능을 추가합니다.

    • VisualShortcutType.Navigate: 사용자가 막대(데이터 포인트) 중 하나를 선택하고 서식 창이 열리면 서식 창에서 색 선택기 카드로 스크롤하여 열립니다.
    • VisualShortcutType.Reset: 바로 가기 메뉴에 초기화 바로 가기를 추가합니다. 채우기 색이 변경된 경우 사용하도록 설정됩니다.
    private getColorSelectorStyles(subSelections: CustomVisualSubSelection[]): SubSelectionStyles {
            const selector = subSelections[0].customVisualObjects[0].selectionId?.getSelector();
            return {
                type: SubSelectionStylesType.Shape,
                fill: {
                    label: 'Fill',
                    reference: {
                        ...colorSelectorReferences.fill,
                     selector
                    },
                },
            };
        }
    

사용자가 막대를 마우스 오른쪽 단추로 클릭하면 다음이 나타납니다.

사용자가 막대를 마우스 오른쪽 단추로 클릭할 때의 사용자 인터페이스 스크린샷.

색을 변경할 때:

색 변경의 스크린샷.

하위 섹션 바로 가기

directEdit에 대한 subSelection 바로 가기 및 스타일을 구현하려면 다음을 수행합니다.

private getDirectEditShortcuts(): VisualSubSelectionShortcuts {
        return [
            {
                type: VisualShortcutType.Reset,
                relatedResetFormattingIds: [
                    directEditReferences.bold,
                    directEditReferences.fontFamily,
                    directEditReferences.fontSize,
                    directEditReferences.italic,
                    directEditReferences.underline,
                    directEditReferences.fontColor,
                    directEditReferences.textProperty
                ]
            },
            {
                type: VisualShortcutType.Toggle,
                relatedToggledFormattingIds: [{
                    ...directEditReferences.show,
                }],
                ...directEditReferences.show,
                disabledLabel: 'Delete',
            },
            {
                type: VisualShortcutType.Picker,
                ...directEditReferences.position,
                label: 'Position'
            },
            {
                type: VisualShortcutType.Navigate,
                destinationInfo: { cardUid: directEditReferences.cardUid },
                label: 'Direct edit'
            }
        ];
    }

이 바로 가기는 바로 가기 메뉴에 관련 메뉴 항목을 추가하고 다음 기능을 추가합니다.

  • VisualShortcutType.Reset: relatedResetFormattingIds 배열에 제공된 속성 중 하나가 변경되면 바로 가기 메뉴의 기본 항목에 초기화를 추가합니다.
  • VisualShortcutType.Toggle: 바로 가기 메뉴에 삭제 옵션을 추가합니다. 클릭하면 directEdit 카드의 토글 스위치가 꺼집니다.
  • VisualShortcutType.Picker: directEdit에 대한 서식 지정 카드에 위치 슬라이스를 추가했기 때문에 오른쪽과 왼쪽 중에서 선택할 수 있는 옵션을 바로 가기 메뉴에 추가합니다.
  • VisualShortcutType.Navigate: 형식 창이 열려 있고 사용자가 directEdit 요소를 선택하면 형식 창이 스크롤되어 directEdit 카드가 열립니다.
private getDirectEditStyles(): SubSelectionStyles {
        return {
            type: powerbi.visuals.SubSelectionStylesType.Text,
            fontFamily: {
                reference: {
                    ...directEditReferences.fontFamily
                },
                label: 'font family'
            },
            bold: {
                reference: {
                    ...directEditReferences.bold
                },
                label: 'bold'
            },
            italic: {
                reference: {
                    ...directEditReferences.italic
                },
                label: 'italic'
            },
            underline: {
                reference: {
                    ...directEditReferences.underline
                },
                label: 'underline'
            },
            fontSize: {
                reference: {
                    ...directEditReferences.fontSize
                },
                label: 'font size'
            },
            fontColor: {
                reference: {
                    ...directEditReferences.fontColor
                },
                label: 'font color'
            },
            background: {
                reference: {
                    objectName: 'directEdit',
                    propertyName: 'background'
                },
                label: 'background'
            }
        }
    }

formattingSettings에 추가할 때 관련 속성을 제공했습니다.

다음 이미지는 directEdit 요소를 마우스 오른쪽 단추로 클릭할 때 UI가 어떻게 보이는지 보여 줍니다.

직접 편집 인터페이스의 스크린샷.

지역화

시각적 개체는 지역화를 처리하고 지역화된 문자열을 제공해야 합니다.

GitHub 리소스

  • 모든 개체 서식 지정 인터페이스는 on-object-formatting-api.d.ts의 (API가 릴리스되면 제공될 링크)에서 찾을 수 있습니다.
  • [HTMLSubSelectionHelper](API가 릴리스되면 제공될 링크)가 포함된 [개체 기반 유틸리티]를 사용하는 것이 좋습니다.
  • API 버전 5.8.0을 사용하고 개체 기반 유틸리티를 사용하여 개체 기반 서식에 대한 지원을 구현하는 사용자 지정 시각적 개체 SampleBarChart의 예를 (API가 릴리스되면 제공되는 링크)에서 찾을 수 있습니다.