Angular Highcharts - How to enable noData options and update it dynamically

4.2k Views Asked by At

I am locally using following highcharts dependencies:

  • "angular-highcharts": "5.2.12"
  • "highcharts": "6.1.0"
  • "@types/highcharts": "5.0.19"

Here is a live demo of of my source code,

First of all I would like to point out that the usage and enabling of the noData functionality for highCharts is quite shady. There is no proper guideline available any where regarding how to use it properly.

Now coming on to the issue, few days back I realized the need to show a proper "no data available" message instead of showing empty charts. I did some research and found that it can be enabled in highcharts and found a working demo of it in plain JavaScript. So now how can we use it with Angular 5? That required some more R&D and finally I figured it out,

import * as noDataToDisplay from 'highcharts/modules/no-data-to-display.src';
...    
@NgModule({
  ...
  providers: [
  { provide: HIGHCHARTS_MODULES, useFactory: () => [noDataToDisplay] }
]

(note: ^^ this approach is not working on the linked stackBlits demo, not sure why! )

I did succeeded in enabling it locally in my repo using the above way, but its not robust, i.e. it does not appears consistently.

Next I wanted to toggle noData message dynamically, i.e update it programmatically so I am tried the following approach:

const options = this.chartConfig.ref.options;
  options.lang.noData = `no data from: ${chartData.customMsgFromDate} to ${chartData.customMsgEndDate}.`;
this.chartConfig.ref.update(options, true);

This did worked once when you toggle the visibility of the series from the legend box, but again this also doesn't seems to be working now though. I have following questions,

  1. What is the proper way of using noData option with angular 5
  2. How to make sure it appears consistently? probably different configuration like setData([]) or setData(null) makes it appears in consistently, but I am not able to find out one root cause behind its inconsistency.
  3. How can I toggle noData message dynamically.

Also if there is anything I can improve do let me know, thanks in advance.

P.S I did manage to find this fiddle regarding achieving things using plain JavaScript but haven't been able to achieve anything using angular highcharts. Here is the code attached fiddle seems to be using.

if (!chart.hasData()) {
    chart.hideNoData();
    chart.showNoData("Your custom error message");
}

probably these methods are not available for the highcharts version I am using.

Thanks to @Pandiyan for fixing the issue with the stackBlitz import.

UPDATE: When locally I try to change NoDataToDisplay import from,

import * as noDataToDisplay from 'highcharts/modules/no-data-to-display.src';

to,

import NoDataToDisplay from 'highcharts/modules/no-data-to-display';

I get the following import error.

enter image description here

due to which I am getting the following errors, when I try to follow @daniel_s answer.

enter image description here

All of my dependencies are in sync, with the provided stackBlitz. I also

  • removed my node_modules folder and re installed all my dependencies.
  • Updated @types/highcharts to the latest version.
3

There are 3 best solutions below

6
On BEST ANSWER
  1. What is the proper way of using noData option with angular 5
  2. How to make sure it appears consistently? probably different configuration like setData([]) or setData(null) makes it appears in consistently, but I am not able to find out one root cause behind its inconsistency.
  3. How can I toggle noData message dynamically.

Re 1. The noData module should work automatically, so if you will add some point to one of your currently visible series, then the "no-data" message disappears. Similarly, when you remove() the series points, so that the series will be empty, then the "no-message" information will be visible on the chart. In case of using it manually, of course you can do it just like you mentioned above. Here is the simple example of use (with buttons included): https://stackblitz.com/edit/highcharts-toggling-nodata-w5fwkf

Re 2. Looks fine if using setData([]) and setData(null). Here is the example: https://stackblitz.com/edit/highcharts-toggling-nodata-54xrqh . If you mean something different, could you describe your question more precisely?

Re 3. If you mean change the noData message dynamically, you should set the chart.options.lang.noData property equal to some new string, then call chart.hideNoData() and chart.showNoData to refresh element value. Here is the example applied to the ng: https://stackblitz.com/edit/highcharts-toggling-nodata-hwnzcl

[EDIT]

Refering to your question update, in order to use a specific module directly within component and not by setting it in providers, just delete the { provide: HIGHCHARTS_MODULES, useFactory: () => [NoDataToDisplay] } from app.module.ts file, and load appropriate module in app.component.ts using require() syntax, like below:

import Highcharts from 'highcharts';

const noData = require('highcharts/modules/no-data-to-display')
noData(Highcharts)

Live example: https://stackblitz.com/edit/highcharts-toggling-nodata-muxx9s

Kind regards!

**

2
On

Try out this

import NoDataToDisplay from 'highcharts/modules/no-data-to-display';

...

{ provide: HIGHCHARTS_MODULES, useFactory: () => [NoDataToDisplay] }  

Slackblitz

0
On

Try this:

import { default as NoData } from 'highcharts/modules/no-data-to-display';
NoData(Highcharts);