物件上格式化可讓使用者直接選取想要修改的元素,快速且輕鬆地修改視覺效果的格式。 選取元素時,格式窗格會自動瀏覽並展開所選元素的特定格式設定。 作為物件上格式化的一部分,子選取服務可用來將子選取項目和大綱傳送至 Power BI。
如何使用子選取項目 API
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的陣列、物件的 objectName 應該與 capabilities.json中所宣告的陣列,以及所選資料點的 selectionId (如果存在) 相同。 - displayName:如果視覺效果支援當地語系化,則顯示名稱應該當地語系化。
- subSelectionType:子選取項目的類型 (圖形、文字或數值文字)。
- selectionOrigin:子選取項目元素的座標。
- showUI:是否要顯示這個子選取項目的 UI,例如格式化操作功能表和工具列。
- immediateDirectEdit:如果應該觸發立即直接編輯,則要編輯的子選取項目大綱的識別碼。
如果您沒有使用 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 事件新增事件接聽程式。
我們想使用 Record 來管理大綱。
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);
}