@howtimeflies/ngx-highcharts

A Highcharts wrapper for Angular (version 4 and newer)

Stats

StarsIssuesVersionUpdatedCreatedSize
@howtimeflies/ngx-highcharts
001.2.03 years ago4 years agoMinified + gzip package size for @howtimeflies/ngx-highcharts in KB

Readme

CircleCI Codecov dependencies devDependencies peerDependencies

npm downloads

ngx-highcharts

A Highcharts wrapper for Angular (version 4 and newer)

  • lazily-load the Highcharts library (60+ KB gzipped) and any additional modules from CDN or your own distribution
  • take advantage of the Highcharts official typings
  • automatically resize the charts to fulfill its container
  • easy installation, configuration, usage and testing, with examples

Installation

yarn add @howtimeflies/ngx-highcharts
yarn add highcharts --dev

or

npm install --save @howtimeflies/ngx-highcharts
npm install --save-dev highcharts

Configuration

Import the module and set the configuration options in app.module.ts

import { HighchartsConfig, HighchartsModule } from '@howtimeflies/ngx-highcharts'

const config: HighchartsConfig = {
  cdnBaseUrl: 'https://code.highcharts.com',
  scriptName: 'highcharts.js',
  delayToExecuteModulesCode: 200,
  maxDelayToResizeContainer: 10000,
  globalOptions: {
    lang: {
      drillUpText: 'Drill-Up'
    }
  }
}

@NgModule({
  imports: [
    ...,
    HighchartsModule
  ],
  providers: [
    { provide: HighchartsConfig, useValue: config }
  ],
  bootstrap: [...]
})
export class AppModule { }

The default configuration options are

public static defaultConfig: HighchartsConfig = {
  // The base url of the Highcharts library on CDN
  cdnBaseUrl: 'https://unpkg.com/highcharts',
  // The javascript file name of the Highcharts library. We could set it to 'highcharts.src.js' in debugging.
  scriptName: 'highcharts.js',
  // The delay in milliseconds to execute the additional Highcharts modules.
  delayToExecuteModulesCode: 500,
  // The max delay in milliseconds to wait the browser to draw the chart. 
  // Only after the chart element is available on DOM, we could resize it to fulfill its container
  maxDelayToResizeContainer: 10000,
  // The global options of Highcharts as listed in https://api.highcharts.com/highcharts/lang
  globalOptions: {}
}

If you would like to use the default configuration options, simply provide an empty object to HighchartsConfig

   { provide: HighchartsConfig, useValue: {} }

The missing options in your custom config would be set with the ones from the default config.

Usage

Add a <ngx-highchart> element to the HTML template. It must be wrapped in a parent container.

<div class="chart-container">
  <ngx-highchart [options]="options" (load)="chart = $event.chart"></ngx-highchart>
</div>

Set the chart options in the typescript code, and get the chart object in the load event handler.

import { Chart, Options } from 'highcharts'
export class ChartComponent {
  public options: Options = {
    chart: { type: 'area' },
    series:[
      {
        name: 'name',
        type: 'area',
        data: []
      }
    ],
    ...
  }

  public chart: Chart
}

Update the chart data dynamically.

this.chart.series[0].setData([1, 0, 3, null, 3, 1, 2, 1])

this.chart.addSeries({
  type: 'area',
  name: 'John',
  data: [0, 1, 4, 4, 5, 2, 3, 7]
})

If some additional highcharts modules are required, set them in the modules attribute.

<div class="chart-container">
  <ngx-highchart [options]="options" [modules]="['modules/drilldown', 'highcharts-more']"
                 (load)="onLoad($event)"></ngx-highchart>
</div>

Set event handlers to the chart

public onLoad(evt: {chart: Chart; highcharts: typeof Highcharts}) {
  this.chart = evt.chart

  evt.chart.series[0].setData(this.data)
  evt.highcharts.addEvent(evt.chart, 'drilldown', it => this.onDrillDown(it))
}

private onDrillDown(evt) {
  const data = this.drillDownData.find(it => it.name === evt.point.name)
  this.chart.addSeriesAsDrilldown(evt.point, data)
}

Test

Install the Highcharts library as a dev dependency: yarn add highcharts --dev or npm install --save-dev highcharts

Verify the chart data and event handler

import * as Highcharts from 'highcharts'
describe(`Drill-down Chart Component`, () => {
  let comp: DrilldownChartComponent
  let fixture: ComponentFixture<DrilldownChartComponent>

  // add the required module
  require('highcharts/modules/drilldown.src')(Highcharts)
  
  beforeEach(async(() => {
    fixture = TestBed.configureTestingModule({
      declarations: [DrilldownChartComponent],
      // import the module for testing
      imports: [HighchartsTestingModule]
    }).createComponent(DrilldownChartComponent)

    fixture.detectChanges()
    comp = fixture.componentInstance
  }))

  it(`should display the data on chart`, () => {
    // retrieve the data from the chart object
    const data = comp.chart.series[0].data.map((it: Highcharts.DataPoint) => [it.name, it.y])

    // verify the data
    expect(data).toContainEqual(['IE', 56.33])
    expect(data).toContainEqual(['Chrome', 24.03])
  })

  it(`should drill down to a pie`, () => {
    let data = null
    // spy on the expecting behavior
    spyOn(comp.chart, 'addSeriesAsDrilldown').and.callFake((x, drillDownData) => data = drillDownData)
    const point = comp.chart.series[0].data[0]
    // simulate an event on the chart object
    Highcharts.fireEvent(comp.chart, 'drilldown', {point})

    // verify the data
    expect(data.name).toEqual('IE')
    expect(data.data).toContainEqual(['v11.0', 24.13])
  })
})

Deployment

With Angular CLI's default ng build, the "highcharts" library is bundled into the production build since it is imported in the project for its typings. angular-cli issue

To work it around, please extend ng build with @angular-builders/custom-webpack:browser, and then mark 'highcharts' as external in the extra webpack config.

Please check the example project for details.

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.