Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.
Hi All,
I am creating a custom visual and implemented Selection and Highlighting successfully.
Unfortunately I still have one strange behavior:
When I select a datapoint after highlighting one or more datapoints in my visual it does not select the datapoint, but does reset the selection.
I have created some screen-shots to show you the issue.
In the first picture below you can see three visuals:
In the second picture I selected the Pens-category in the table and these are highlighted in both other visuals.
So far so good...
In the third picture you can see the result when I select in my Visual the Envelopes-datapoint:
This is still the expected behavior...
When I now click on the Paper-bar in the Clustered Bar Chart-visual to select this category I get the following result:
As you can see the Table-visual and the My Visual show the wrong result, In my Visual the Paper-catagory should be highlighted and in the table visual this categroy should be selected...
After some debugging I found out that the following happens when I select a datapoint in my Visual:
<edited the behavior after additional debugging>
In my debug-data I can see that the visual receives an update (type: 2). This seems to be right because the data is changed (highlights are added) and in my conversion from dataView to dataModel I get the correct settings for each dataPoint. However, I do get a second update immediately (again type 2) and I noticed that in the dataView the highlights are missing so that's why the visual is rendered without any highlight...
Below I have added the following code-parts:
behavior.ts
import * as d3 from "d3";
type Selection<T1, T2 = T1> = d3.Selection<any, T1, any, T2>;
import { interactivityBaseService as interactivityService } from "powerbi-visuals-utils-interactivityutils";
import IInteractiveBehavior = interactivityService.IInteractiveBehavior;
import IInteractivityService = interactivityService.IInteractivityService;
import ISelectionHandler = interactivityService.ISelectionHandler;
import { ColumnPoint } from "./dataInterfaces";
import { IBehaviorOptions } from "powerbi-visuals-utils-interactivityutils/lib/interactivityBaseService";
import { LollipopColumnSettings } from "./settings";
export const DimmedOpacity: number = 0.5;
export const DefaultOpacity: number = 1.0;
const getEvent = () => d3.event;
export function getFillOpacity(
selected: boolean,
highlight: boolean,
hasSelection: boolean,
hasHighlights: boolean
): number {
if ((hasHighlights && !highlight) || (hasSelection && !selected)) {
return DimmedOpacity;
}
return DefaultOpacity;
}
export interface BehaviorOptions extends IBehaviorOptions<ColumnPoint> {
clearCatcher: Selection<any>;
pointSelection: Selection<ColumnPoint>;
interactivityService: IInteractivityService<ColumnPoint>;
settings: ColumnSettings;
contextSelection: Selection<any>;
}
export class Behavior implements IInteractiveBehavior {
private options: BehaviorOptions;
public bindEvents(options: BehaviorOptions, selectionHandler: ISelectionHandler) {
this.options = options;
let clearCatcher = options.clearCatcher;
options.pointSelection.on("click", (dataPoint: ColumnPoint) => {
const event: MouseEvent = d3.event;
selectionHandler.handleSelection(dataPoint, event.ctrlKey || event.metaKey);
event.stopPropagation();
});
clearCatcher.on("click", () => {
selectionHandler.handleClearSelection();
});
}
public renderSelection(hasSelection: boolean) {
const {
pointSelection,
interactivityService
} = this.options;
pointSelection.style("opacity", (dataPoint: ColumnPoint) => {
return getFillOpacity(
dataPoint.selected,
dataPoint.highlight,
hasSelection ,
dataPoint.hasHighlights
);
});
}
}
In my visual.ts I have the following code regarding the interactivityService:
I imported the following:
import { interactivityBaseService as interactivityService, interactivitySelectionService } from "powerbi-visuals-utils-interactivityutils";
import { Behavior, BehaviorOptions } from "./behavior";
In the Visual-class I added the following variables:
private interactivityService: IInteractivityService<ColumnPoint>;
private behavior: Behavior
In the constructor I defined:
this.behavior = new Behavior();
this.interactivityService = createInteractivitySelectionService(this.host);
In the Update-method ( at the end) I defined the following code after I do render the chart:
this.clearCatcher = appendClearCatcher(this.ColumnSvg.selectAll(".data-lines"));
if (this.interactivityService) {
const behaviorOptions: BehaviorOptions = {
clearCatcher: this.clearCatcher,
pointSelection: this.ColumnSvg.select(".data-points").selectAll("circle"),
interactivityService: this.interactivityService,
behavior: this.behavior,
dataPoints: this.viewModel.dataPoints,
settings: this.viewModel.settings,
contextSelection: this.ColumnSvg
};
this.interactivityService.bind(behaviorOptions);
this.behavior.renderSelection(this.interactivityService.hasSelection());
}
I am not sure if it is right to use "this.interactivityService.hasSelection()" to fill the hasSelection-param of the renderSelection-function.
Has some one had the same behavior as I describe above or can some one tell me what I am doing wrong? Thanks in advance!
Regards
Paul
To clarify the issue above I created a GIF that does show the problem:
I hope this gives a better impression what is happening.
Thanks in advance!
Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City
Check out the April 2024 Power BI update to learn about new features.
User | Count |
---|---|
13 | |
2 | |
2 | |
1 | |
1 |
User | Count |
---|---|
20 | |
3 | |
2 | |
2 | |
2 |