Highcharts in Aurelia

Hi All,

I was wondering if anyone uses highcharts in an Aurelia application with typescript. I have been beating my head against the wall trying to get it working and just don’t seem to be getting anywhere.

I am importing highcharts in the following manner:
import * as Highcharts from 'highcharts';

My understanding is that Highcharts is then a namespace and to create a chart I need to use Highcharts.chart() (with the appropriate parameters). The typings and completion from typescript seem to confirm this.

The issue I seem to be having is at runtime I just keep on receiving error messages saying that Highcharts.chart is undefined and when inspecting the Highcharts object in the browser it is simply showing up as: default: {}

I am fairly new to modern JS development so it could just be something really basic and stupid that I am doing wrong.

Any help would be appreciated

2 Likes

Aurelia team got some hardcore language purists (I am not one) :sweat_smile: so that our default typescript project didn’t turn on esModuleInterop.

This option is very important for new JS devs. Turn it on in your tsconfig.json like this:

"compilerOptions": {
    "esModuleInterop": true,
    ...

Then use

import Highcharts from ‘highcharts’;

That should fix your issue.

1 Like

Thanks for the suggestion, but unfortunately I still seem to be having an error. This time it is:

highcharts_1.default.chart is not a function

Any other ideas?

1 Like

Can I see your tsconfig.json and the source code where you import and build a chart?

1 Like

Something is not quite right for highcharts + ts.

I could get it work with following code. But there is some type complain from ts, but it still can run.
These code are on top of an aurelia-cli generated webpack + ts project.

app.ts

import Highcharts from 'highcharts';

export class App {
  public message: string = 'Hello World!';
  container: HTMLElement;

  attached() {
    // this.container uses the element of
    // ref="container" in app.html
    Highcharts.chart(this.container, {
      chart: {
          type: 'bar'
      },
      title: {
          text: 'Fruit Consumption'
      },
      xAxis: {
          categories: ['Apples', 'Bananas', 'Oranges']
      },
      yAxis: {
          title: {
              text: 'Fruit eaten'
          }
      },
      series: [{
          name: 'Jane',
          data: [1, 0, 4]
      }, {
          name: 'John',
          data: [5, 7, 3]
      }]
    });
  }
}

app.html

<template>
  <h1>${message}</h1>
  <div ref="container" style="width:100%; height:400px;"></div>
</template>

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "esnext",
    "skipLibCheck": true,
    "typeRoots": [
      "./node_modules/@types"
    ],
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "target": "es5",
    "lib": [
      "es2015",
      "dom"
    ],
    "moduleResolution": "node",
    "baseUrl": "src",
    "resolveJsonModule": true,
    "allowJs": true
  },
  "include": [
    "./src/**/*.ts",
    "./test/**/*.ts",
    "./types/**/*.d.ts"
  ],
  "atom": {
    "rewriteTsconfig": false
  }
}

1 Like

Thanks so much for your help in looking into this one.

My tsconfig.json is pretty vanilla from the cli project setup, the only real difference I can see is that mine is using amd rather than esnext

{
  "compileOnSave": false,
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "amd",
    "noImplicitAny": false,
    "declaration": false,    
    "types": [
      "node",
      "jest"
    ],
    "typeRoots": [
      "./node_modules/@types"
    ],
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "target": "es5",
    "lib": [
      "es2015",
      "dom"
    ],
    "moduleResolution": "node",
    "baseUrl": "src",
    "resolveJsonModule": true,
    "allowJs": true
  },
  "include": [
    "./src/**/*.ts",
    "./test/**/*.ts",
    "./types/**/*.d.ts"
  ],
  "exclude": [
    "./test/e2e/**/*.ts"
  ],
  "atom": {
    "rewriteTsconfig": false
  }
}

I changed my tsconfig to esnext and although things are not working I did receive a more meaningful error message, but it looks like something is getting mangled somewhere there.

ReferenceError: bel is not defined↵    at eval (eval at __generator (http://localhost:9000/scripts/app-bundle.js), <anonymous>:1:1)↵    at __generator (http://localhost:9000/scripts/app-bundle.js:69:5)↵    at FleetSizeByManufacturer.eval (http://localhost:9000/scripts/app-bundle.js:210:16)↵    at eval (http://localhost:9000/scripts/app-bundle.js:51:35)↵    at new Promise (<anonymous>)↵    at __awaiter (http://localhost:9000/scripts/app-bundle.js:30:12)↵    at FleetSizeByManufacturer.activate (http://localhost:9000/scripts/app-bundle.js:209:14)↵    at tryActivateViewModel (http://localhost:9000/scripts/vendor-bundle.js:34004:28)

My Highcharts call looks like this:

    attached() {

        Highcharts.chart('main', {
          chart: {
              type: 'bar'
          },
          title: {
              text: 'Fruit Consumption'
          },
          xAxis: {
              categories: ['Apples', 'Bananas', 'Oranges']
          },
          yAxis: {
              title: {
                  text: 'Fruit eaten'
              }
          },
          series: [{
              name: 'Jane',
              data: [1, 0, 4]
          } as Highcharts.SeriesOptionsType, {
              name: 'John',
              data: [5, 7, 3]
          } as Highcharts.SeriesOptionsType]
        });
    }
1 Like

As ugly as it may be I decided to stop fighting with highcharts, and just prepended the highcharts.js file.

2 Likes

Since you are not using webpack, I tried your code in an aurelia-cli built-in bundler typescript project, it worked for me again with the same type error in terminal.

But prepend works best, I am glad you pick that route. I myself uses prepend for highcharts too, also use prepend to set highcharts global options.

FYI: regarding why it failed for you but not for me, one thing you can try is au clear-cache to reset aurelia-cli built-in bundler cache (you might have some bad cache from an old version of the aurelia-cli bundler).

2 Likes