0
votes

I am trying to use Highmaps in an angular-cli app with angular2-highcharts package.

I want to use a specific map (http://code.highcharts.com/mapdata/custom/world.js) that I saved into my assets/map directory, and linked in .angular-cli.json (apps[0].scripts).

NgModule

import { ChartModule } from 'angular2-highcharts';
...
imports: [
  ChartModule.forRoot(
    require('highcharts/highmaps'),
  ),
}

component.ts:

    const Highcharts = require('highcharts');

    this.mapOptions = {
      title: {
        text: 'Zoom in on country by double click',
      },

      mapNavigation: {
        enabled: false,
        enableDoubleClickZoomTo: true
      },

      colorAxis: {
        min: 1,
        max: 1000,
        type: 'logarithmic',
      },

      series: [{
        data: data.audience.distributionByCountry,
        mapData: Highcharts.maps['custom/world'],
        joinBy: ['iso-a2', 'code'],
        name: 'Population density',
        states: {
          hover: {
            color: '#a4edba',
          },
        },
        tooltip: {
          valueSuffix: '/kmĀ²',
        },
      }],
    };

html

The error (generated by Angular's addScript.js) complains that the Highcharts is not defined.

Out of curiosity I tried to add the following:

Highcharts = Highcharts || {maps: {}};

at the beginning of the map file so see if that was the problem, but it didn't solve the case.

What should I do to get the locally saved map to work?

EDIT

Detailed attempt report

Attempt 1

@NgModule

import { ChartModule } from 'angular2-highcharts';

declare const Highcharts: any;
require('highcharts/modules/map')(Highcharts);

import '../../assets/maps/world.js';
...
imports: [
  ChartModule.forRoot(
    Highcharts,
  ),
]

Compile error

Error encountered resolving symbol values statically. Reference to a local (non-exported) symbol 'Highcharts'. Consider exporting the symbol (position 21:15 in the original .ts file), resolving symbol InsightsModule in /Users/armo/Code/origami/src/app/insights/insights.module.ts

Attempt 2

import { ChartModule } from 'angular2-highcharts';
import * as Highcharts from 'highcharts';
import '../../assets/maps/world.js';

Runtime error

ERROR Error: Uncaught (in promise): ReferenceError: Highcharts is not defined ReferenceError: Highcharts is not defined

1

1 Answers

1
votes

To load maps you could try with something like:

import { ChartModule } from 'angular2-highcharts';
import * as Highcharts from 'highcharts/highmaps';

// add your maps here as they will be added to Highcharts variable
...
imports: [
  ChartModule.forRoot(
    Highcharts
  ),
}

You are using Highcharts.maps['custom/world'] so you should load the file with map. The file is JS script that adds to Highcharts.maps the map file that is later used in chart's config.

If there are problems with loading Highmaps you could try with Highcharts + map module. However, the Angular2-highcharts using forRoot with modules applied internally to the Highcharts and without adding map module first there will not be Highcharts.maps, so you will not be able to load any maps - you could try with:

import * as Highcharts from 'highcharts';
require('highcharts/modules/map')(Highcharts);
// add maps here
...
imports: [
  ChartModule.forRoot(
    Highcharts // this will pass Highcharts with the map module and maps
  ),
}

Another option would be to replace mapData: Highcharts.maps['custom/world'], in series config with content of the map file.

EDIT:

Here's a demo for using Highmaps with angular2-highcharts: http://plnkr.co/edit/AmDfKwhRhshFn3CPprkk?p=preview

If you wan to load mapData from file I suggest loading it as a JSON data from GeoJSON files in map collection or nest the JS map file with same code as modules have (example):

(function(factory) {
    if (typeof module === 'object' && module.exports) {
        module.exports = factory;
    } else {
        factory(Highcharts);
    }
}(function(Highcharts) {
...
// map file here
...
}));

Next, you could load this as other modules - require('./path-to-map/your-edited-map-file')' in 'forRoot'. You might need to setallowJstotrueincompilerOptionsintsconfig.json` on top level of your angular app.