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}`,
}];
}
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
}
}
}
this.host is undefined in the constructor. Please take host object form options at contrcutor.
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
- satishr8 years agoHelper III
Thanks v-viig. Added the line this.host = options.host; in the constructor. The error is gone now but the tool tip is still not working :( What else am I missing? I can send you the full code files if needed.
- v-viig8 years agoCommunity Champion
satishr yes, please share the full source code.
You might share the code here or send it to [email protected]
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
- BrentonC6 years agoHelper I
This is what I was missing when the visual would not show up.