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.
Hello,
I'm working on a custom visual and I have very basic a square that when you move on it, it displays a tooltip. (the tooltip should display a report page).
i Used the addTooltip Method like the description on learn.microsoft.com.
visual.ts
"use strict";
import "core-js/stable";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
import powerbiVisualsApi from "powerbi-visuals-api";
import VisualEnumerationInstanceKinds = powerbiVisualsApi.VisualEnumerationInstanceKinds;
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import IVisual = powerbi.extensibility.visual.IVisual;
import DataView = powerbi.DataView;
import IVisualHost = powerbi.extensibility.visual.IVisualHost;
import * as d3 from "d3";
import {
select as d3Select
} from "d3-selection";
import {
scaleLinear,
scaleBand
} from "d3-scale";
//tooltip imports
import VisualTooltipDataItem = powerbi.extensibility.VisualTooltipDataItem;
import { createTooltipServiceWrapper, ITooltipServiceWrapper, TooltipEventArgs } from "powerbi-visuals-utils-tooltiputils";
import { csvParseRows, Numeric, schemeSet3, treemapSquarify } from "d3";
import DataViewMetadataColumn = powerbi.DataViewMetadataColumn;
import DataViewTable = powerbi.DataViewTable;
import DataViewTableRow = powerbi.DataViewTableRow;
import PrimitiveValue = powerbi.PrimitiveValue;
import ISelectionId = powerbi.visuals.ISelectionId;
type Selection<T extends d3.BaseType> = d3.Selection<T, any, any, any>;
export class Visual implements IVisual {
private host: IVisualHost;
private svg: Selection<SVGElement>;
private container: Selection<SVGElement>;
private rect: Selection<SVGElement>;
private textValue: Selection<SVGElement>;
private tooltipServiceWrapper: ITooltipServiceWrapper;
private table: HTMLParagraphElement;
private selection: d3.Selection<d3.BaseType, any, d3.BaseType, any>;
constructor(options: VisualConstructorOptions) {
this.svg = d3.select(options.element)
.append('svg')
.classed('excel2', true);
this.host = options.host;
this.container = this.svg.append("g")
.classed('container', true);
this.tooltipServiceWrapper = createTooltipServiceWrapper(this.host.tooltipService, options.element);
this.rect = this.container.append("rect")
.classed('rect', true);
this.textValue = this.container.append("text")
.classed("textValue", true);
this.table = document.createElement("table");
this.target.appendChild(this.table);
}
public update(options: VisualUpdateOptions) {
let dataView: DataView = options.dataViews[0];
let tableDataView: DataViewTable = dataView.table;
let width: number = options.viewport.width;
let height: number = options.viewport.height;
let index = dataView.table.rows.length - 1;
this.svg
.attr("width", width)
.attr("height", height);
//TEXT hinzufügen und Ausrichtung
let fontSizeValue: number = Math.min(width, height) / 8;
if (width < height) {
this.container.selectAll("text")
.attr("transform", "rotate(-90)")
this.textValue
.text(<string>dataView.table.rows[0][1])
.attr("x", -(height / 2))
.attr("y", width / 2)
.attr("text-anchor", "middle")
.style("font-size", fontSizeValue + "px");
} else {
this.textValue
.text(<string>dataView.table.rows[0][1])
.attr("x", width / 2)
.attr("y", height / 2)
.attr("text-anchor", "middle")
.style("font-size", fontSizeValue + "px")
.attr("transform", "rotate(0)");
}
//rechteck für statusanzeige
this.rect
.style("fill-opacity", 0.5)
.style("stroke", "black")
.style("stroke-width", 5)
.attr("width", width)
.attr("height", height);
//[....]
this.tooltipServiceWrapper.addTooltip(
this.svg.selectAll('rect'),
(tooltipEvent: TooltipEventArgs<number>) => Visual.getTooltipData(tooltipEvent.data),
(tooltipEvent: TooltipEventArgs<number>) => null,
true);
}
public static getTooltipData(value: any): VisualTooltipDataItem[] {
return [{
displayName: value,
value: value,
color: value,
header: 'tooltip title'
}];
}
}
And ich declare the getTooltipData method also (with examples just to try if its work)
capabilities.json
"tooltips": {
"supportedTypes": {
"default": true,
"canvas": true
},
"roles": [
"Tooltips"
],
"supportEnhancedTooltips": true
}
Can someone possibly help me and tell me what I have to consider?
Thank you
Hi @Anonymous,
The issue is in the third parameter of your addTooltip method, i.e.:
this.tooltipServiceWrapper.addTooltip(
this.svg.selectAll('rect'),
(tooltipEvent: TooltipEventArgs<number>) => Visual.getTooltipData(tooltipEvent.data),
(tooltipEvent: TooltipEventArgs<number>) => null, <--- THIS PART
true);
This expects an ISelectionId and you are passing null to it, which means that Power BI has no context for the tooltip columns and measures needed to resolve it on your behalf.
You will need to create a selection for the desired data point that the element represents, so that Power BI can resolve it for you and display the correct canvas tooltip.
Provided that the desired column or measure is included in your selection, and the report page tooltip contains one of these then it should then resolve as you expect.
If you want to see an example of this, the MS sampleBarChart has the addTooltip call here, and the selection ID creation as part of mapping the dataset here.
Good luck!
Daniel
Proud to be a Super User!
My course: Introduction to Developing Power BI Visuals
On how to ask a technical question, if you really want an answer (courtesy of SQLBI)
Hey Daniel, Whats messed up w/ OPs code is actually how MS has it in their documentation:
https://learn.microsoft.com/en-us/power-bi/developer/visuals/add-tooltips#call-the-addtooltip-method
this.tooltipServiceWrapper.addTooltip(this.barContainer.selectAll('.bar'),
(tooltipEvent: TooltipEventArgs<number>) => BarChart.getTooltipData(tooltipEvent.data),
(tooltipEvent: TooltipEventArgs<number>) => null);
I suspect what MS meant to enter was
this.tooltipServiceWrapper.addTooltip(this.barContainer.selectAll('.bar'),
(tooltipEvent: TooltipEventArgs<number>) => BarChart.getTooltipData(tooltipEvent.data),
null);
Which would would work but only to display static information... The documenation and examples is all over the place and broken for this.
Hello Daniel,
thank you for your quick reply. My data structure is a table data view. on the page: https://learn.microsoft.com/de-de/power-bi/developer/visuals/selection-api . Is described how this works however I don't know what "rowDiv" does?!
const dataView = options.dataViews[0];
dataView.table.rows.forEach((row: DataViewTableRow, rowIndex: number) => {
this.target.appendChild(rowDiv); <-- here
const selection: ISelectionId = this.host.createSelectionIdBuilder()
.withTable(dataView.table, rowIndex)
.createSelectionId();
}
I am new in creating custom Visials please forgive me 😄
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 |
---|---|
15 | |
2 | |
1 | |
1 | |
1 |