Power BI visuals interactivity utils
Interactivity utils (InteractivityUtils
) is a set of functions and classes that can be used to simplify the implementation of cross-selection and cross-filtering.
Note
The latest updates of interactivity utils support only the latest version of tools (3.x.x and above).
Installation
To install the package, run the following command in the directory with your current Power BI visual project.
npm install powerbi-visuals-utils-interactivityutils --save
If you're using version 3.0 or later of the tool, install
powerbi-models
to resolve dependencies.npm install powerbi-models --save
To use interactivity utils, import the required component in the source code of the Power BI visual.
import { interactivitySelectionService } from "powerbi-visuals-utils-interactivityutils";
Include CSS files
To use the package with your Power BI visual, import the following CSS file to your .less
file.
node_modules/powerbi-visuals-utils-interactivityutils/lib/index.css
Import the CSS file as a .less
file because the Power BI visuals tool wraps external CSS rules.
@import (less) "node_modules/powerbi-visuals-utils-interactivityutils/lib/index.css";
SelectableDataPoint properties
Usually, data points contain selections and values. The interface extends the SelectableDataPoint
interface.
SelectableDataPoint
already contains properties as follows:
/** Flag for identifying that a data point was selected */
selected: boolean;
/** Identity for identifying the selectable data point for selection purposes */
identity: powerbi.extensibility.ISelectionId;
/*
* A specific identity for when data points exist at a finer granularity than
* selection is performed. For example, if your data points select based
* only on series, even if they exist as category/series intersections.
*/
specificIdentity?: powerbi.extensibility.ISelectionId;
Defining an interface for data points
Create an instance of interactivity utils and save the object as a property of the visual.
export class Visual implements IVisual { // ... private interactivity: interactivityBaseService.IInteractivityService<VisualDataPoint>; // ... constructor(options: VisualConstructorOptions) { // ... this.interactivity = interactivitySelectionService.createInteractivitySelectionService(this.host); // ... } }
import { interactivitySelectionService } from "powerbi-visuals-utils-interactivityutils"; export interface VisualDataPoint extends interactivitySelectionService.SelectableDataPoint { value: powerbi.PrimitiveValue; }
Extend the base behavior class.
Note
BaseBehavior
was introduced in the 5.6.x version of interactivity utils. If you use an older version, create a behavior class from the following sample.Define the interface for the behavior class options.
import { SelectableDataPoint } from "./interactivitySelectionService"; import { IBehaviorOptions, BaseDataPoint } from "./interactivityBaseService"; export interface BaseBehaviorOptions<SelectableDataPointType extends BaseDataPoint> extends IBehaviorOptions<SelectableDataPointType> { /** d3 selection object of the main elements on the chart */ elementsSelection: Selection<any, SelectableDataPoint, any, any>; /** d3 selection object of some elements on backgroup, to hadle click of reset selection */ clearCatcherSelection: d3.Selection<any, any, any, any>; }
Define a class for
visual behavior
. Or, extend theBaseBehavior
class.Define a class for
visual behavior
The class is responsible for
click
andcontextmenu
mouse events.When a user clicks data elements, the visual calls the selection handler to select data points. If the user clicks the background element of the visual, it calls the clear selection handler.
The class has the following correspond methods:
bindClick
bindClearCatcher
bindContextMenu
.
export class Behavior<SelectableDataPointType extends BaseDataPoint> implements IInteractiveBehavior { /** d3 selection object of main elements in the chart */ protected options: BaseBehaviorOptions<SelectableDataPointType>; protected selectionHandler: ISelectionHandler; protected bindClick() { // ... } protected bindClearCatcher() { // ... } protected bindContextMenu() { // ... } public bindEvents( options: BaseBehaviorOptions<SelectableDataPointType>, selectionHandler: ISelectionHandler): void { // ... } public renderSelection(hasSelection: boolean): void { // ... } }
Extend the
BaseBehavior
classimport powerbi from "powerbi-visuals-api"; import { interactivitySelectionService, baseBehavior } from "powerbi-visuals-utils-interactivityutils"; export interface VisualDataPoint extends interactivitySelectionService.SelectableDataPoint { value: powerbi.PrimitiveValue; } export class Behavior extends baseBehavior.BaseBehavior<VisualDataPoint> { // ... }
To handle a click on elements, call the d3 selection object
on
method. This also applies forelementsSelection
andclearCatcherSelection
.protected bindClick() { const { elementsSelection } = this.options; elementsSelection.on("click", (datum) => { const mouseEvent: MouseEvent = getEvent() as MouseEvent || window.event as MouseEvent; mouseEvent && this.selectionHandler.handleSelection( datum, mouseEvent.ctrlKey); }); }
Add a similar handler for the
contextmenu
event, to call the selection manager'sshowContextMenu
method.protected bindContextMenu() { const { elementsSelection } = this.options; elementsSelection.on("contextmenu", (datum) => { const event: MouseEvent = (getEvent() as MouseEvent) || window.event as MouseEvent; if (event) { this.selectionHandler.handleContextMenu( datum, { x: event.clientX, y: event.clientY }); event.preventDefault(); } }); }
To assign functions to handlers, the interactivity utils calls the
bindEvents
method. Add the following calls to thebindEvents
method:bindClick
bindClearCatcher
bindContextMenu
public bindEvents( options: BaseBehaviorOptions<SelectableDataPointType>, selectionHandler: ISelectionHandler): void { this.options = options; this.selectionHandler = selectionHandler; this.bindClick(); this.bindClearCatcher(); this.bindContextMenu(); }
The
renderSelection
method is responsible for updating the visual state of elements in the chart. A sample implementation ofrenderSelection
follows.public renderSelection(hasSelection: boolean): void { this.options.elementsSelection.style("opacity", (category: any) => { if (category.selected) { return 0.5; } else { return 1; } }); }
The last step is creating an instance of
visual behavior
, and calling thebind
method of the interactivity utils instance.this.interactivity.bind(<BaseBehaviorOptions<VisualDataPoint>>{ behavior: this.behavior, dataPoints: this.categories, clearCatcherSelection: select(this.target), elementsSelection: selectionMerge });
selectionMerge
is the d3 selection object, which represents all the visual's selectable elements.select(this.target)
is the d3 selection object, which represents the visual's main DOM elements.this.categories
are data points with elements, where the interface isVisualDataPoint
orcategories: VisualDataPoint[];
.this.behavior
is a new instance ofvisual behavior
created in the constructor of the visual, as shown:export class Visual implements IVisual { // ... constructor(options: VisualConstructorOptions) { // ... this.behavior = new Behavior(); } // ... }
Next steps
Feedback
Submit and view feedback for