Forum Discussion
Highlight resets when update() is called
- 8 months ago
Hi ,
Highlight resets when update() is called after my visual selection
This is expected behavior in the custom visuals API, and it comes from how cross-highlighting vs. your own selection are represented:When another visual drives the selection, the host can send a highlights array in your dataView (if your visual declares supportsHighlight: true). You read those highlights and render a partial emphasis. Microsoft Learn+1
When your visual drives the selection, the selection state is not echoed back via the highlights array. Instead, the host triggers an update() (often with a data query) and expects you to restore the selection using the Selection Manager (ISelectionManager). In other words: highlights are for cross-visual input, selection manager is for your visual’s own state. Microsoft Learn
So what you’re observing—first click selects, host fires update(), highlights are empty and your selection appears “lost” until a second click—usually means the visual is clearing its own selection because it only trusts highlights and isn’t restoring from the Selection Manager.
What to change
Declare highlight support (for cross-visual)
In capabilities.json, keep:
"dataViewMappings": [ ... ],
"supportsHighlight": true
Then use categorical.values[i].highlights only when present (that means another visual is selecting).Own your selection state (for self-selection)
Use ISelectionManager to store and restore selected ISelectionIds.
On click in your visual:
await selectionManager.select(selectionId, multiSelect);
// Optionally set a guard flag here (see #3)In update(options), don’t clear selection just because highlights is null/undefined. Instead:
If highlights exist → render cross-highlight.
Else if selectionManager.getSelectionIds().length > 0 → render your own selected points (re-apply the visual styling based on those IDs).
Else → render default (no selection).
Documentation for the Selection API: Microsoft Learn+1Ignore the “echo” update caused by your own click (optional but helpful)
The host often re-queries and calls update() right after your select(). Add a short-lived guard flag so your next update() doesn’t wipe your in-memory selection while the new dataView is arriving.Example pattern:
private skipNextUpdate = false;
onDataPointClick(selectionId) {
this.skipNextUpdate = true;
selectionManager.select(selectionId).then(() => {
// let the host call update()
});
}public update(options: VisualUpdateOptions) {
if (this.skipNextUpdate) {
this.skipNextUpdate = false;
// Repaint using selectionManager.getSelectionIds()
this.renderFromSelectionManagerOrHighlights(options);
return;
}
this.renderFromSelectionManagerOrHighlights(options);
}Branch logic on update type (optional)
You can check options.type (e.g., VisualUpdateType.Data, Resize, Style) to decide how aggressively to rebind or redraw. This won’t bring back highlights, but it helps reduce flicker and accidental clears.Did I answer your question? Mark my post as a solution! Appreciate your Kudos !!
Hi YCbCr,
Thank you johnbasha33 for your response to the query.
Has your issue been resolved?
If the response provided by the community member addressed your query, could you please confirm? It helps us ensure that the solutions provided are effective and beneficial for everyone.
Thank you.