Forum Discussion
Custom Visual - Selecting, Filtering and Highlighting
- 8 years ago
Partial solution to the selection problems (issues 1 and 2), but not the fact that other visuals are filtered not highlighted (3).
The problem stems from the fact that when more than one category column is add to createSelectionIdBuilder() it causes the cross-filtering to error when more than one data point is selected.
The fix is to only add one category column to the createSelectionIdBuilder - it doesn't matter which one, and the values in the column appear to be irrelevant. This is counter intuitive if comparing with an SQL select, or any other filtering function which would look to match against the values in the category columns. The resultant code (showing the removed line commented out) is as follows:
const selectionId: ISelectionId = this.host.createSelectionIdBuilder() .withCategory(ageRange, i) // .withCategory(gender, i) .createSelectionId();It would be helpful if PowerBI provided a more useful error message, or error checking, to advise that more than one category is not permitted when cross filtering; or even, have a solution which doesn't throw an error when more than one category is selected.
Hello diaAzul
- SelectionManager.select allows to select multiple data points (selectionIds) if the second argument is true
- Advanced Filter API doesn't support filtering by multiple columns
- How do you implement selection? Do you use SelectionManager.select?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
- diaAzul8 years ago
Advocate IV
Thanks,
1/ I've tried selectionManager as well - that doesn't work for cross filtering more than one data point. Note there is a difference between selection and cross-visual filtering. Interactive services works for selection (i.e. selecting multiple points within the custom visual) but doesn't work for cross-visual filtering within the same report.
2/ Agreed. The question is how can I cross-filter visuals, selecting multiple dataPoints (SelectionId)? Each time I try and implement this it causes PowerBI to throw an error in the other visuals in the report.
3/ I am using selectionHandler and BindEvents within the interactive services. SelectionHandler is the method on InteractiveServices class; selectionFilter is my own class within which basic and advancced filters are constructed/applied; DataPoint.convert() is a method to extract the datum from the d3 SVGElement.
public bindEvents(params: ISelectionToolsParams, selectionHandler: ISelectionHandler): void { this.params = params; this.selectionHandler = selectionHandler; this.bindClickEventToClearCatcher(); this.params.visualDataPoints.on('click', (el: SVGElement): void => { this.selectionFilter.reset(); this.selectionHandler.handleSelection(DataPoint.convert(el), (d3.event as MouseEvent).ctrlKey); this.selectionHandler.applySelectionFilter(); (d3.event as MouseEvent).stopPropagation(); }); this.params.categories.on('click', (el: SVGElement): void => { if (!(d3.event as MouseEvent).ctrlKey) { this.clearSelection(); } this.selectionFilter.addCondition(this.visFilterColumnTargets.ageRange, 'Is', (el as any)); this.selectionFilter.apply(); this.params.visualDataPoints.data().forEach((d: SVGElement) => { const dataPoint: IDataPoint = DataPoint.convert(d); if (dataPoint.age === (el as any)) { this.selectionHandler.handleSelection(dataPoint, true); } }); (d3.event as MouseEvent).stopPropagation(); }); }Part of the problem is that PowerBI cusom visual API has not yet matured, it may do so over the next 12-18 months, but for now we are looking at other solutions.
- v-viig8 years ago
Community Champion
How do you construct SelectionId? Can you share code snippet?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
- diaAzul8 years ago
Advocate IV
Thank you v-viig
The data consists of two category columns and two measure columsn:
ageRange(Category) Gender(Category) Value(Measure) Reference(Measure) A0-4 Male 5,000 5,500 A0-4 Female 4,500 6,000 A5-9 Male 5,500 5,500 A5-9 Female 4,600 6,000 ... A85+ Female 1,500 900
Selection/Filtering is on both AgeRange and Gender.
SelectionId Code (summarised):
const dataView: DataView = data.dataViews[0]; const ageRange: DataViewCategoryColumn = dataView.categorical.categories[0]; const gender: DataViewCategoryColumn = dataView.categorical.categories[1]; const valueColumn: DataViewValueColumn = dataView.categorical.values[fieldIndices[interfaceFields.values]]; const refColumn: DataViewValueColumn = dataView.categorical.values[fieldIndices[interfaceFields.reference]]; for (let i: number = 0; i < dataView.categorical.categories[0].values.length; i++) { const selectionId: ISelectionId = this.host.createSelectionIdBuilder() .withCategory(ageRange, i) .withCategory(gender, i) .createSelectionId(); chartViewModel.dataPoints.push(new DataPoint({ age: <string>ageRange.values[i], gender: <string>gender.values[i], value: getValues(interfaceFields.values, i) || 0, reference: getValues(interfaceFields.reference, i) || 0, highlightValue: getHighlights(interfaceFields.values, i) || 0, highlightReference: getHighlights(interfaceFields.reference, i) || 0, identity: selectionId, specificIdentity: selectionId, highlighted: isHighlighted, selected: false })); }Link to code in-situ on gitHub
For reference the error message when two or more individual points are selected is included below: