Forum Discussion
Custom visual tooltip service not working
- 8 years ago
Thank you for sharing. We're going to look into the issue.
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
- 8 years ago
v-viig Thanks for sharing the solution. Below were the changes done in my code.
this.tooltipServiceWrapper.addTooltip(this.svg.selectAll('.bar'),(tooltipEvent: TooltipEventArgs<BarData>) => Visual.getTooltipData(tooltipEvent.data),(tooltipEvent: TooltipEventArgs<BarData>) => null);
private static getTooltipData(data: BarData): VisualTooltipDataItem[] {
return [{
displayName: data.Date,
value: `${data.Indicator}`,
}];
}
Did you implement createTooltipServiceWrapper?
Can you share the whole source code of your custom visual?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
- satishr8 years agoHelper III
Copied tooltipServiceWrapper.ts file from https://github.com/Microsoft/PowerBI-visuals-sampleBarChart and pasted in my src folder.
Added "src/tooltipServiceWrapper.ts" to tsconfig.json files part.
Below is my visual.ts. Please let me know if I'm missing anything.
Now, the visual doesn't show anything. If I comment the first line in the constructor the bar graph shows without tooltips.module powerbi.extensibility.visual { "use strict"; import ValueFormatter = powerbi.extensibility.utils.formatting.valueFormatter; export interface BarData { Indicator: number; Category: string; } export class Visual implements IVisual { private svg: d3.Selection<SVGElement>; private g: d3.Selection<SVGElement>; private host: IVisualHost; private tooltipServiceWrapper: ITooltipServiceWrapper; private bColorPos: string; private bColorNeg: string; constructor(options: VisualConstructorOptions) { this.tooltipServiceWrapper = createTooltipServiceWrapper(this.host.tooltipService, options.element); this.svg = d3.select(options.element).append('svg'); this.g = this.svg.append('g'); this.bColorPos = "#32CD32"; this.bColorNeg = "#FD625E"; } public update(options: VisualUpdateOptions) { this.setObjectProperties(options); this.generateBarChart(options); } public setObjectProperties(options: VisualUpdateOptions) { if (options.dataViews[0].metadata.objects) { if (options.dataViews[0].metadata.objects["bar"] && options.dataViews[0].metadata.objects["bar"]["bColorPos"]) {this.bColorPos = options.dataViews[0].metadata.objects["bar"]["bColorPos"]["solid"]["color"].toString();} if (options.dataViews[0].metadata.objects["bar"] && options.dataViews[0].metadata.objects["bar"]["bColorNeg"]) {this.bColorNeg = options.dataViews[0].metadata.objects["bar"]["bColorNeg"]["solid"]["color"].toString();} } } public generateBarChart(options: VisualUpdateOptions){ var _this = this; var barColor1 = this.bColorPos; var barColor2 = this.bColorNeg; _this.svg.attr({ height: options.viewport.height, width: options.viewport.width }); var gHeight = options.viewport.height * 0.5; var gWidth = options.viewport.width ; _this.g.attr({ height: gHeight, width: gWidth }); _this.g.attr('transform','translate(0,0)'); // convert data format var data = Visual.dataForBarGraph(options); // setup d3 scale var xScale = d3.scale.ordinal() .domain(data.map(function (d) { return d.Category; })) .rangeRoundBands([0, gWidth], 0.1); var yMax = d3.max(data, function (d) { return d.Indicator }); var yScale = d3.scale.linear() .domain([0, yMax]) .range([gHeight, 0]) // remove exsisting axis and bar _this.svg.selectAll('.bar').remove(); // draw bar var shapes = _this.g .append('g') .selectAll('.bar') .data(data); shapes.enter() .append('rect') .attr('class', function (d) { return d.Indicator < 0 ? "bar negative" : "bar positive"; }) .attr('fill', function (d) { return d.Indicator < 0 ? barColor2 : barColor1; }) .attr('x', function (d) { return xScale(d.Category); }) .attr('width', xScale.rangeBand()) .attr('y', function (d) { return d.Indicator < 0 ? yScale(0) : yScale(d.Indicator); }) .attr('height', function (d) { return d.Indicator < 0 ? yScale(d.Indicator) - yScale(0) : gHeight - yScale(d.Indicator); }) this.tooltipServiceWrapper.addTooltip(this.svg.selectAll('.bar'), (tooltipEvent: TooltipEventArgs<number>) => Visual.getTooltipData(tooltipEvent.data), (tooltipEvent: TooltipEventArgs<number>) => null); shapes.exit().remove(); } public static dataForBarGraph(options: VisualUpdateOptions): BarData[] { var resultData: BarData[] = []; var rows = options.dataViews[0].table.rows; for (var i = 0;i < rows.length;i++) { var row = rows[i]; resultData.push({ Indicator: +row[0].toString(), Category: row[2].toString() }); } return resultData; } public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration { let objectName = options.objectName; let objectEnumeration: VisualObjectInstance[] = []; switch (objectName) { case 'bar': objectEnumeration.push({ objectName: objectName, properties: { bColorPos: this.bColorPos, bColorNeg: this.bColorNeg, }, selector: null }); break; }; return objectEnumeration; } private static getTooltipData(value: any): VisualTooltipDataItem[] { return [{ displayName: value.category, value: value.value.toString(), color: value.color }]; } public destroy(): void { //TODO: Perform any cleanup tasks here } } }- v-viig8 years agoCommunity Champion
this.host is undefined in the constructor. Please take host object form options at contrcutor.
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals