6.0.2 • Published 1 month ago

powerbi-visuals-utils-onobjectutils v6.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 month ago

Installation

Run the following command to install the util:

    npm i powerbi-visuals-utils-onobjectutils

On-object utils

The HTMLSubSelectionHelper provides an easy way for your Power BI custom visual to emit subselections to Power BI, get and render outlines.

HTMLSubSelectionHelper is a helper class intended to facilitate the creation and subsequent management of subselection outlines. It contains methods for finding subselectable elements.

The utils exports CSS classes and attributes making it easier for the visual to define and maintain subselections.

To define subselectable elements, we also need to add a class to each desired element.

CSS ClassPurposeRequired
subselectableProvides a selector for the HTMLSubSelectionHelper to find possible subselectionsyes

To define subselections for the visual, there are a few attributes that need to be added to the desired elements.

Attribute NameAttributePurposeRequiredTypeExample
SubSelectableDisplayNameAttributedata-sub-selection-display-nameProvide a localized string for display name of the subselected elementyesstringdata-sub-selection-display-name="Visual Title"
SubSelectableObjectNameAttributedata-sub-selection-object-nameProvide an object name to associate with subselection shortcuts and styleyesstringdata-sub-selection-object-name="title"
SubSelectableTypeAttributedata-sub-selection-typeProvide the type of the subselected styleyesSubSelectionStylesTypedata-sub-selection-type="1"
SubSelectableDirectEditdata-sub-selection-direct-editProvide direct text edit references, including the CardUID, GroupUID, and the orientation of the text boxnoSubSelectableDirectEdit should be provided as a stringdata-sub-selection-direct-edit="{"reference":{"cardUid":"Visual-title","groupUid":"title-text","sliceUid":"title-text-text"},"style":0}"
SubSelectableHideOutlineAttributedata-sub-selection-hide-outlineProvide a boolean value for subselectable elements that shouldn't have an outline shownnobooleandata-sub-selection-hide-outline="true"
SubSelectableRestrictingElementAttributedata-sub-selection-restricting-elementUsed to indicate the element that will be restricted, the outlines, and the type of restriction (clamp or clip)noSubSelectionOutlineRestrictionTypedata-sub-selection-restricting-element="1"
SubSelectableSubSelectedAttributedata-sub-selection-sub-selectedIndicate whether the subselectable is selected or notNo, the helper assigns it to the elements when neededBooleandata-subselection-sub-selected="true"

Format mode

When the visual enters format mode, You need to disable interactivity for the visual, as we expect the user to select the visual and visual element to initiate formatting.

HTMLSubSelectionHelper public methods

The HTMLSubSelectionHelper has some public methods that you can use, but there are two main methods and the helper does the rest.

The two methods are setFormatMode and updateOutlinesFromSubSelections.

The public methods of the helper include:

  • createHtmlSubselectionHelper(args: HtmlSubselectionHelperArgs): HtmlSubSelectionHelper - This is a static method that takes args of type HtmlSubselectionHelperArgs and returns an instance of HTMLSubSelectionHelper.

  • setFormatMode(isFormatMode: boolean): void - This method sets the format mode for the HTMLSubSelectionHelper, If isFormatMode is true, the helper attaches relevant event listeners to the host element to enable format mode functionality (subselecting, rendering outlines).

  • getSubSelectionSourceFromEvent(event: PointerEvent): HtmlSubSelectionSource | undefined - returns an HtmlSubSelectionSource object that is built according to the event parameter.

  • onVisualScroll(): void - Indicates to the HTMLSubSelectionHelper that scrolling is currently occurring. Scrolling should remove outlines until scrolling is finished.

  • updateElementOutlines(elements: HTMLElement[], visibility: SubSelectionOutlineVisibility, suppressRender: boolean = false): SubSelectionRegionOutlineId[] - update the outlines (and emits them to Power BI to be rendered) of the elements.

  • clearHoveredOutline(): void - This method clears hovered outlines if they exist.

  • updateRegionOutlines(regionOutlines: HelperSubSelectionRegionOutline[], suppressRender: boolean = false): void - update and emits the given outlines to get rendered.

  • getElementsFromSubSelections(subSelections: CustomVisualSubSelection[]): HTMLElement[] - given subSelections, this method returns the relevant HTMLElements.

  • updateOutlinesFromSubSelections(subSelections: CustomVisualSubSelection[], clearExistingOutlines?: boolean, suppressRender?: boolean): void - updates and renders the outlines for the given subSelection with respect to suppressRender and clearExistingOutlines.

  • hideAllOutlines(suppressRender: boolean = false): void - hide all the outlines with respect to suppressRender.

  • getAllSubSelectables(filterType?: SubSelectionStylesType): CustomVisualSubSelection[] - returns all the subSelectables according to the filterType.

  • createVisualSubSelectionForSingleObject(createVisualSubSelectionArgs: CreateVisualSubSelectionFromObjectArgs): CustomVisualSubSelection - create CustomVisualSubSelection object from the createVisualSubSelectionArgs.

  • setDataForElement(el: HTMLElement | SVGElement, data: SubSelectionElementData): void - a static method that sets data for the elements.

  • getDataForElement(el: HTMLElement | SVGElement): SubSelectionElementData - a static method that gets the associated previously assigned using setDataForElement.

HtmlSubselectionHelperArgs

interface HtmlSubselectionHelperArgs {
    /** Element which contains the items that can be sub-selected */
    hostElement: HTMLElement; // The host element, the helper will attach the listeners to this element
    subSelectionService: powerbi.extensibility.IVisualSubSelectionService;// subSelectionService which is provided in powerbi-visuals-api
    selectionIdCallback?: ((e: HTMLElement) => ISelectionId);// a callback that gets the selectionId for the specific element
    customOutlineCallback?: ((subSelection: CustomVisualSubSelection) => SubSelectionRegionOutlineFragment[]);// a callback to get custom outline for the specific subSelection
    customElementCallback?: ((subSelection: CustomVisualSubSelection) => HTMLElement[]);
    subSelectionMetadataCallback?: ((subSelectionElement: HTMLElement) => unknown);// a callback to attatch any meta data to the subSelection.
}

SubSelectionStylesType

const enum SubSelectionStylesType {
            None = 0,
            Text = 1,
            NumericText = 2,
            Shape = 3,
}

SubSelectableDirectEdit

interface SubSelectableDirectEdit {
            reference: SliceFormattingModelReference;
            style: SubSelectableDirectEditStyle;
            displayValue?: string;
}

SubSelectionOutlineRestrictionType

const enum SubSelectionOutlineRestrictionType {
            /**
             * A clamping element will adjust the outline to prevent it from extending beyond
             * the restricting element.
             */
            Clamp,
            /**
             * A clipping element will make parts of the outline not visible if the outline extends beyond the
             * restricting element's bounds. 
             */
            Clip
        }

To add restriction options to a specific element use the HTMLSubSelectionHelper setDataForElement with this data type, the helper uses the data to update the outlines:

interface SubSelectionElementData {
    outlineRestrictionOptions?: SubSelectionOutlineRestrictionOptions;
}

/** Options used to indicate if a restricting element should allow outlines more space to
  * generate by adding padding or if the restricting element should constrict the outline more
  * by adding a margin.
  */
export interface SubSelectionOutlineRestrictionOptions {
        padding?: IOffset;
        margin?: IOffset;
  }

Example

In this example, we implement customOutlineCallback and selectionIdCallback: The following code is in Visual Code. We have an object in the visual called arcElement. We want to render the outline when the element is hovered or subselected.

import ISelectionId = powerbi.visuals.ISelectionId;

const enum BarChartObjectNames {
    ArcElement = 'arcElement',
    ColorSelector = 'colorSelector',
    …..
}

private ArcOutlines(subSelection: CustomVisualSubSelection): powerbi.visuals.SubSelectionRegionOutlineFragment[] {
        const outlines: powerbi.visuals.SubSelectionRegionOutlineFragment[] = []
        if (subSelection?.customVisualObjects[0].objectName === BarChartObjectNames.ArcElement) {
            const outline: powerbi.visuals.ArcSubSelectionOutline = {
                type: powerbi.visuals.SubSelectionOutlineType.Arc,
                center: { x: this.arcCenterX, y: this.arcCenterY },
                startAngle: this.arcStartAngle,
                endAngle: this.arcEndAngle,
                innerRadius: this.arcInnerRadius,
                outerRadius: this.arcOuterRadius
            };
            outlines.push({
                id: BarChartObjectNames.ArcElement,
                outline
            });
            return outlines;
        }
    }

public selectionIdCallback(e: Element): ISelectionId {
        const elementType: string = d3.select(e).attr(SubSelectableObjectNameAttribute);
        switch (elementType) {
            case BarChartObjectNames.ColorSelector:
                const datum = d3.select<Element, BarChartDataPoint>(e).datum();
                return datum.selectionId;
            default:
                return undefined;
        }
    }
And in the constructor code we will create the HTMLSubSelectionHelper

constructor(options: VisualConstructorOptions) {
    …….
    this.subSelectionHelper = HtmlSubSelectionHelper.createHtmlSubselectionHelper({
                hostElement: options.element,
                subSelectionService: options.host.subSelectionService,
                selectionIdCallback: (e) => this.selectionIdCallback(e),
                customOutlineCallback: (e) => this.ArcOutlines(e),
            });
    ….
}

In update method of the visual add the following code to update the outlines of the subSeselection, update the state of the format mode for the HTMLSubSelectionHelper and disable interactions that aren't for format mode if format mode is on:

public update(options: VisualUpdateOptions) {
 …
 
 if (this.formatMode) {// disabling interaction with the visual data in format mode
             barSelectionMerged.on('click', null);
             this.svg.on('click', null);
             this.svg.on('contextmenu', null);
         } else {
             this.handleBarClick(barSelectionMerged);
             this.handleClick(barSelectionMerged);
             this.handleContextMenu();
         }
         this.subSelectionHelper.setFormatMode(options.formatMode);
         const shouldUpdateSubSelection = options.type & powerbi.VisualUpdateType.Data
             || options.type & powerbi.VisualUpdateType.Resize
             || options.type & powerbi.VisualUpdateType.FormattingSubSelectionChange;
         if (this.formatMode && shouldUpdateSubSelection) {
             this.subSelectionHelper.updateOutlinesFromSubSelections(options.subSelections, true);
         }
 …
}
6.0.2

1 month ago

6.0.1

2 months ago

6.0.0

2 months ago