Поделиться через


API вложенных выборов (предварительная версия)

Форматирование в объекте позволяет пользователям быстро и легко изменять формат визуальных элементов, напрямую выбирая элементы, которые они хотят изменить. При выборе элемента область форматирования автоматически перемещается и расширяет определенный параметр форматирования для выбранного элемента. В рамках форматирования объекта служба вложенных выборов используется для отправки вложенных выборов и контуров в Power BI.

Использование API subselection

Служба SubSelection предоставляет два метода:

subSelect

Отправляет вложенный выбор для Power BI, который будет использоваться, когда пользователь выбирает элемент, позволяющий выполнять подселекцию.

subSelect(args: visuals.CustomVisualSubSelection | undefined): void

CustomVisualSubSelection
interface CustomVisualSubSelection {
            customVisualObjects: CustomVisualObject[];
            displayName: string;
            subSelectionType: SubSelectionStylesType;
            selectionOrigin: SubSelectionOrigin;
            /** Whether to show the UI for this sub-selection, like formatting context menus and toolbar */
            showUI: boolean;
            /** If immediate direct edit should be triggered, the ID of the sub-selection outline to edit */
            immediateDirectEdit?: string;
            metadata?: unknown;
        }


interface CustomVisualObject {
            objectName: string;
            selectionId: powerbi.visuals.ISelectionId | undefined;
        }

Этот метод имеет следующие параметры:

  • customVisualObjects: массив, содержащий customVisualObjectsобъект, объектName объекта должен совпадать с объявленным в capabilities.json, и selectionId для выбранной точки данных, если она существует.
  • displayName: отображаемое имя должно быть локализовано, если визуальный элемент поддерживает локализацию.
  • subSelectionType: тип подселектора (фигура, текст или числовый текст).
  • selectionOrigin: координаты выбранного элемента.
  • showUI: отображение пользовательского интерфейса для этого подселектора, например форматирование контекстных меню и панели инструментов.
  • интерпретацияDirectEdit: если следует активировать немедленное прямое редактирование, идентификатор структуры подселектора для изменения.

Если вы не используете HTMLSubSelectionHelperэтот параметр, необходимо управлять вложенными выборами.

Пример вложенного выбора

В этом примере мы добавим прослушиватель событий в элемент узла для событий контекстного меню правой кнопкой мыши.

constructor(options: VisualConstructorOptions) {
        this.hostElement = options.element;
        this.subSelectionService = options.host.subSelectionService;
        ….
}

public update(options: VisualUpdateOptions) {
 if (options.formatMode) {
             // remove event listeners which are irrelevant for format mode.
   …
             this.hostElement.addEventListener('click', this.handleFormatModeClick);
             this.hostElement.addEventListener('contextmenu',  this.handleFormatModeContextMenu);
         } else {
             this.hostElement.removeEventListener('click', this.handleFormatModeClick);
             this.hostElement.removeEventListener('contextmenu', this.handleFormatModeContextMenu);
   …
             // add event listeners which are irrelevant for format mode
         }
 }
 
private handleFormatModeClick(event: MouseEvent): void {
        this.subSelectFromEvent(event, true /**showUI */);
    }

 private handleFormatModeContextMenu(event: MouseEvent): void {
        this.subSelectFromEvent(event, false);
    }

private subSelectFromEvent(event: MouseEvent, showUI: boolean): void {
        //find the element which was selected and fill the needed fields
        const cVObject: powerbi.visuals.CustomVisualObject = {
            objectName: 'myObject',//the object name that is relevant to the clicked element
            selectionId: undefined
        };
        const subSelection: CustomVisualSubSelection = {
            customVisualObjects: [cVObject],
            displayName: 'myObject',
            selectionOrigin: {
                x: event.clientX,
                y: event.clientY
            },
            subSelectionType: SubSelectionStylesType.Shape,// choose the relevant type
            showUI
        };
        this.subSelectionService.subSelect(subSelection);
    }

updateRegionOutlines

Этот метод отправляет контуры в Power BI для отрисовки. Используйте его в update методе визуального элемента, так как это место, где Power BI отправляет вложенный выбор, отправленный ранее визуальным элементом. Его также можно использовать, если требуется отобразить структуру для наведенного элемента.

updateRegionOutlines(outlines: visuals.SubSelectionRegionOutline[]): void

SubSelectionRegionOutline
interface SubSelectionRegionOutline {
            id: string;
            visibility: SubSelectionOutlineVisibility; // controls visibility for outlines
            outline: SubSelectionOutline;
        }

Если вы не используете HTMLSubSelectionHelperэтот параметр, необходимо вручную управлять контурами и их состоянием (если они активны, наведите указатель мыши или не видимый).

Пример структуры региона обновления

В этом примере предполагается, что у нас есть объект, который myObjectвызывается, и мы хотим отобразить контур прямоугольника при наведении указателя на соответствующий элемент. Мы используем код в предыдущем примере для subSelect.

В обновлении также необходимо добавить прослушиватель событий для pointerover события.

Мы хотим управлять нашими структурами с помощью записи.

private subSelectionRegionOutlines: Record<string, SubSelectionRegionOutline > = {};


public update(options: VisualUpdateOptions) {
 if (options.formatMode) {
             // remove event listeners which are irrelevant for format mode.
   …
             this.hostElement.addEventListener('click', this.handleFormatModeClick);
             this.hostElement.addEventListener('contextmenu',  this.handleFormatModeContextMenu);
   this.hostElement.addEventListener('pointerover', this.handleFormatModePointerOver);
         } else {
             this.hostElement.removeEventListener('click', this.handleFormatModeClick);
             this.hostElement.removeEventListener('contextmenu', this.handleFormatModeContextMenu);
   this.hostElement.removeEventListener('pointerover', this.handleFormatModePointerOver);
   …
             // add event listeners which are irrelevant for format mode
         }
 }
 
 private handleFormatModePointerOver(event: MouseEvent): void {
         // use the event to extract the element that was hovered.
         // in this example we assume that we found the element and it is related to object called myObject.
         // we need to clear previously hovered outlines before rendering
         const regionOutlines = getValues(this.subSelectionRegionOutlines);
         const hoveredOutline = regionOutlines.find(outline => outline.visibility === SubSelectionOutlineVisibility.Hover);
         if (hoveredOutline) {
             this.subSelectionRegionOutlines[hoveredOutline.id] = {
                 ...this.subSelectionRegionOutlines[hoveredOutline.id],
                 visibility: powerbi.visuals.SubSelectionOutlineVisibility.None
             };
         }
         // now we will build the outline for myObject relevant element.
         let element: HTMLElement;// assume we found the relevant element.
         const domRect = element.getBoundingClientRect();
         const { x, y, width, height } = domRect;
         const outline: powerbi.visuals.RectangleSubSelectionOutline = {
             height,
             width,
             x,
             y,
             type: powerbi.visuals.SubSelectionOutlineType.Rectangle,
         };
     
         const regionOutline: powerbi.visuals.SubSelectionRegionOutline = {
             id: 'myObject',
             visibility: powerbi.visuals.SubSelectionOutlineVisibility.Hover,
             outline
         };
         this.subSelectionRegionOutlines[regionOutline.id] = regionOutline;
         this.renderOutlines();
         // you need to remove the hovered outline when the element is not hovered anymore
     }
     private renderOutlines(): void {
         const regionOutlines = getValues(this.subSelectionRegionOutlines);
         this.subSelectionService.updateRegionOutlines(regionOutlines);
     }