I'm using Highcharts to display an interactive map with custom countries and I need to activate the drilldown feature, i.e. clicking on a country to zoom in on another map with internal states of that country.
The way to go on about this in angular is to add a drilldown event handler to a chartOptions object, load the map data within and then call a function to add the map data as drilldown in the chart.
export class MapComponent implements OnInit {
public chartOptions: Highcharts.Options = {
chart: {
events: {
drilldown(e) {
// At this point "this" is a Highcharts.MapChart object.
const chart = this as any;
const mapKey = `countries/ca/${e.point.drilldown}-all`;
const mapData = require(`@highcharts/map-collection/${mapKey}.geo.json`);
const provinceData = Highcharts.geojson(mapData);
// Filling map data with meaningless values becaus it's just an example.
provinceData.forEach((el: any, i) => { el.value = i; });
// Here's the key, the Highcharts.MapChart object is required to add the new map data.
chart.addSeriesAsDrilldown(e.point, { name: e.point.name, data: provinceData });
}
}
}
}
}
However, since I'm not using one of the provided map data from Highcharts but custom map data generated from an SVG file and located in a mongo db, which is loaded from the database on startup and stored in a property of my MapComonent, I need to access that property using "this" in the scope of the component within the event handler function.
export class MapComponent implements OnInit {
private drilldownData: Highcharts.SeriesMapOptions = { ... };
public chartOptions: Highcharts.Options = {
chart: {
events: {
// Here "this" is of course in the scope of the MapComponent.
drilldown: this.handleDrilldown
}
}
}
private handleDrilldown(e: Highcharts.DrilldownEventObject): void {
// At this point "this" is a Highcharts.MapChart object.
let chart = this as any;
// Now, of course, the drilldownData is undefined because "this" required here is not the MapComponent.
chart.addSeriesAsDrilldown(e.point, { name: e.point.name, data: this.drilldownData });
}
}
I've tried calling the drilldown as drilldown: event => this.handleDrilldown(event) but then "this" inside the handleDrilldown is the MapComponent and I have no way of getting to the Highcharts.MapChart object. The same applies with drilldown: this.handleDrilldown.bind(this) which overwrites the internal scope to the MapComponent's. drilldown: function(event) { this.handleDrilldown(event) } of course won't work either, because now "this" inside the function already is the Highcharts.MapChart object and thus doesn't have the handleDrilldown method. Is there a way for me to somehow pass the drilldownData into the event handler in this constellation while maintaining the scope of the Highcharts.MapChart inside of the event handler?