Using angular-google-charts
(Angular 13.2), I need to create a TreeMap with a custom tooltip. The GoogleChartComponent has an options property named generateTooltip that takes a callback function. From that function, I need to access data that is a property of the Angular component (chart.data) that contains the GoogleChartComponent. But I can't access the component's property from within the callback function. The examples on Google's website are understandably straight JavaScript.
<!-- dashboard.component.html -->
<google-chart
[data]="chart.data"
[options]="chart.options"
[title]="chart.title"
[type]="chart.type"
[columns]="chart.columns"
[height]="chart.height"
style="width: 100%"
></google-chart>
// dashboard.component.ts
import { Component, OnInit } from '@angular/core'
import { ChartType} from 'angular-google-charts'
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
public chart = {
title: '',
type: ChartType.TreeMap,
data: [
['Global', null, 0, 0, 'Global'],
['Americas', 'Global', 0, 0, 'Global'],
['EMEA', 'Global', 0, 0, 'Global'],
['Acme - Lab 1YR (New)', 'Americas', 326000, 100, 'Susan Moore'],
['Flexa - DevOps 1YR (New)', 'Americas', 206000, 0, 'Jeremy Young'],
['Organo - CI/CD 1YR (New)', 'EMEA', 188000, 0, 'Sif Nilsen'],
['Ny Carlsberg Glyptotek - Automated Test Lab 300 devices 1YR (New)', 'EMEA', 212000, 0, 'Nils Peter Bjørnsen'],
['Dunder Mifflin - SCM 2YR (New)', 'Americas', 448000, 50, 'Justin Case']
],
columns: [
{type: 'string', label: 'Opportunity', role: 'domain'},
{type: 'string', label: 'Parent', role: 'data'},
{type: 'number', label: 'Amount', role: 'tooltip'},
{type: 'number', label: 'Score', role: 'data'},
{type: 'string', label: 'Owner', role: 'tooltip'}
],
options: {
minColor: '#f00',
midColor: '#ddd',
maxColor: '#0d0',
headerHeight: 0,
fontFamily: 'Nunito',
fontSize: 13,
fontColor: 'black',
generateTooltip: this._showFullTooltip
},
height: 290,
}
constructor () {
}
_showFullTooltip(row: number, size: number, value: number) {
// This is where I need to get values out of this.chart.data[row]
const amount = size.toLocaleString('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });
const tooltip = `<div style="color:#fff; background:#313A4B; padding: 10px; border-width:1px; border-style: solid; border-color:#fff;">${amount}</div>`
return tooltip;
}
}
In the example above, one of the parameters passed to the callback is row. I need to get this.chart.data[row]
. This doesn't work. I am thinking it's because the callback function works outside of Angular but I'm not sure what is the best way to connect the _showFullTooltip() function to component properties.
Any recommendations?
This is not an Angular issue, rather JS scoping. Instead of assigning generateTooltip: this._showFullTooltip
, bind the scope to the function as well like so generateTooltip: this._showFullTooltip.bind(this)
.
When you pass along a function reference the this
keyword will be the context of whoever/whatever is invoking that function. By using the .bind(this)
you overwrite the function invocation context with the current assignee context (DashboardComponent). This should allow you to use this.chart.data[row]
in your _showFullTooltip
function.