Forum Discussion

satishr's avatar
satishr
Helper III
8 years ago
Solved

Custom visual tooltip service not working

I'm writing a custom visual with some KPIs and a bar chart. I have created the bar chart by following the below article.
https://tsmatz.wordpress.com/2016/09/27/power-bi-custom-visuals-programming/

The visual is working fine. Now I want a display a tooltip when mouse hovered on the bar chart. I followed the below documentation (couldn't understand most of it) and implemented the same.
https://github.com/Microsoft/PowerBI-visuals/blob/master/Visual/Tooltips.md

 

My visual doesn't show anything. When I cross-checked the culprit was this line in the constructor.

this.tooltipServiceWrapper = createTooltipServiceWrapper(this.host.tooltipService, options.element);

When I commented this line, my visual works fine. What I'm I doing wrong? How to get the tooltips working?
Please help asap!
  • Thank you for sharing. We're going to look into the issue. 

     

    Ignat Vilesov,

    Software Engineer

     

    Microsoft Power BI Custom Visuals

    [email protected]

  • 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}`,
    }];
    }

11 Replies

  • v-viig's avatar
    v-viig
    Community Champion

    Did you implement createTooltipServiceWrapper?

     

    Can you share the whole source code of your custom visual?

     

    Ignat Vilesov,

    Software Engineer

     

    Microsoft Power BI Custom Visuals

    [email protected]

    • satishr's avatar
      satishr
      Helper 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-viig's avatar
        v-viig
        Community 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

        [email protected]

    • satishr's avatar
      satishr
      Helper III

      v-viig I have posted my code. Can you please help me with this? I have a tight deadline to deliver this custom visual to my client.