99
Views
10
Comments
Solved
[Solid Gauge Chart] Use Highcharts gauge chart in addition to 'normal' charts
solid-gauge-chart
Reactive icon
Forge asset by Sherif Diab
Application Type
Reactive
Service Studio Version
11.54.15 (Build 62559)

Hello all,

I have used (and customized) the Solid Gauge charts component, since it allows me to create a HighCharts chart with type 'solidgauge'. However, it does need to load the 3 javascript files for it to work:

When navigating from a Gauge chart page, to a page that has the normal HighCharts widget, I now get a HighCharts error #16, since highcharts is defined multiple times:

Uncaught Error: Highcharts error #16: www.highcharts.com/errors/16/

Do you have any recommendation on how to work with both chart widgets, but prevent this error?

Thanks,
Remco

2024-01-04 15-15-51
Abed Al Banna
Solution

Hi Remco,

I have another suggestion, I think this would work better.

1. Go to any screen in which you are using a normal OutSystems chart, open dev tools and type "Highcharts.version" in the console to get the current Highcharts version which OutSystems Charts is using. If you are using the latest version of OutSystems Charts, then the Highcharts version will most likely be 10.3.2. Note this version down.


2. Go to Highcharts Changelog | Highcharts, scroll down to find the version in question, download the Highcharts folder, then extract all of its files.


3. Go to the extracted files -> code and add the 2 "highcharts.js" and "highcharts-more.js" scripts to your app. Delete the 3 old scripts (related to v9.1).


4. Go to the SolidGaugeChart, modify the InitializeChart as follows:

a. Javascript node to check whether Highcharts is already loaded or not:

function isHighchartsLoaded() {

  return typeof Highcharts !== 'undefined';

}


$parameters.IsHighchartsLoaded = isHighchartsLoaded()


b. If Highcharts is loaded, then skip the first 2 scripts (highcharts.js and highcharts-more.js) and load the solid-gauge.js script from this URL: "https://code.highcharts.com/modules/solid-gauge.js", otherwise if they are not loaded, load the 2 scripts from their uploaded URL.


c. Keep the rest of the code the same.


Make sure you remove everything related to the client variable and refresh approach that we defined at first.

You might still get the Error #16 when navigating from a screen that has the gauge chart to another screen that has a normal OutSystems chart, but this error won't have any effect on the loading/rendering of the charts, you can only see it through the console. The loaded Highcharts version will be the same as the one OutSystems Charts is built on, so this wouldn't cause any issues.


I will attach the OML to this reply. Try this approach out and let me know if it works better than the full-page refresh.


Best regards,

Abed

TestCharts.oml
2024-01-04 15-15-51
Abed Al Banna

Hi @Remco Snijders 

Is it possible to attach your OML, or a sample OML that has your implementation? A closer look would help in solving this issue.

By "normal Highcharts widget" do you mean the OutSystems charts? As they are also customized Highcharts.

Best regards,

Abed

2021-02-16 20-34-58
Remco Snijders
 
MVP

Please find attached the OML. In the console, you see the #16 highcharts error when you switch between the highcharts and the gauge chart screen. I wonder if there's a way to prevent it...

I indeed use OutSystems charts.

TestCharts.oml
2024-01-04 15-15-51
Abed Al Banna

Hi @Remco Snijders 

Please try the following:

1. Decouple the Solid Gauge chart and move it from the Forge Component into your block, completely, by moving the 3 structures, the SolidGaugeChart, and the 3 scripts into your app.

2. Go to the "Menu" block, and do the following:

a. Add a new client variable "ForceReload" of data type Boolean.

b. Add a new screen (client) action GaugeChartOnClick, in which you set the value of the "ForceReload" client variable to True and then redirect the user to the GaugeChart screen.


c. Change the OnClick event handler of the Menu link to GaugeChartOnClick.


3. Add an OnInitialize event handler to the screen that contains the Gauge Chart (GaugeChart), in which you check the value of the ForceReload client variable, if it's true, you reload the screen which forces the JavaScript VM to unload the scripts, and then reset the value of ForceReload.

Note that you have to replace the "TestCharts" and "GaugeChart" by the names of your entry module and Gauge screen, respectively, you can also make this dynamic to be fetched automatically.

4. Now to go to the OnInitialize screen action of the SolidGaugeChart block, add an If node at first checking the value of ForceReload, if it's true, add 3 RequireScript screen actions in which you load the 3 necessary JavaScript scripts. Also add an Exception handler on "All Exceptions". The rest of the flow remains unchanged. 

Scripts.highcharts9_1.URL

Scripts.highchartsmore9_1.URL

Scripts.solidgauge9_1.URL


5. Make sure you remove all 3 scripts from the Required Scripts of the block, as you are loading them programmatically with this approach. You shouldn't have any scripts loaded here.

 

Let me know if this solves your issue! I will be also attaching the OML file here.


Best regards,

Abed

TestCharts.oml
2024-01-04 15-15-51
Abed Al Banna

Apologies, I forgot to elaborate on this approach.

Basically the error is stemming from the fact that the Highcharts.js and Highcharts-more.js are being loaded twice as you correctly mentioned. 

Initially, if you open the page that contains the highcharts, OutSystems Highcharts.js and Highcharts-more.js get loaded, then when you navigate to the Gauge screen, the JavaScript VM attempts to load the Highcharts.js and Highcharts-more.js coming from the Gauge block, and this is what triggers the error. 

The issue is that once the code compiles, the JavaScript VM of the browser executes those scripts and stores them, so that even if you successfully remove the scripts from the DOM, they would still be loaded by the VM. From what I know this cannot be undone, you cannot explicitly unload or remove JavaScript code from the JavaScript VM once it has been loaded and executed. JavaScript code becomes part of the page's runtime environment, and it remains in memory as long as the page is open or until the page is refreshed or closed. 

The only solution I could think of is if you navigate from any loaded screen to the Gauge screen, that contains the Gauge chart that requires the 3 aforementioned scripts, you do a full page refresh which clears all the DOM and loaded JavaScript, then after that step is done you basically load the 3 scripts required for this specific screen. This step can be bypassed if you directly open that specific Gauge screen (from a URL pointing to Gauge screen for example), that way no refresh is needed as you are not navigating to it from a page that had loaded the 2 scripts mentioned above.


I hope this helps.

2021-02-16 20-34-58
Remco Snijders
 
MVP

Thanks for your elaborate answer Abed. I indeed understand the problem and the way you prevent it from happening.

Since I preferred a solution that does not require the full page refresh and is easier to maintain, I decided to adjust the GaugeChart widget to accept custom JSON and thereby also be able to render other types of charts.

When the widget is a bit cleaner, I will upload it in the forge.

2024-01-04 15-15-51
Abed Al Banna

Hi @Remco Snijders 

I'm curious to know whether you managed to solve that issue or not, and if you found another solution for it, it would be good to share that approach as well :)

Best,

Abed

2021-02-16 20-34-58
Remco Snijders
 
MVP

Hi Abed,

We did go ahead and implemented your solution (since we are now including the gauge chart into an application with more charts). However, we are running into two issues:

- The multiple charts error does appear when going the other way around (from gauge chart to default chart);

- That can of course be solved by also forcing a refresh there, but it leads to a quite nasty flash of the screen (we are trying to implement it with a mobile transition).

Any ideas?

2024-01-04 15-15-51
Abed Al Banna
Solution

Hi Remco,

I have another suggestion, I think this would work better.

1. Go to any screen in which you are using a normal OutSystems chart, open dev tools and type "Highcharts.version" in the console to get the current Highcharts version which OutSystems Charts is using. If you are using the latest version of OutSystems Charts, then the Highcharts version will most likely be 10.3.2. Note this version down.


2. Go to Highcharts Changelog | Highcharts, scroll down to find the version in question, download the Highcharts folder, then extract all of its files.


3. Go to the extracted files -> code and add the 2 "highcharts.js" and "highcharts-more.js" scripts to your app. Delete the 3 old scripts (related to v9.1).


4. Go to the SolidGaugeChart, modify the InitializeChart as follows:

a. Javascript node to check whether Highcharts is already loaded or not:

function isHighchartsLoaded() {

  return typeof Highcharts !== 'undefined';

}


$parameters.IsHighchartsLoaded = isHighchartsLoaded()


b. If Highcharts is loaded, then skip the first 2 scripts (highcharts.js and highcharts-more.js) and load the solid-gauge.js script from this URL: "https://code.highcharts.com/modules/solid-gauge.js", otherwise if they are not loaded, load the 2 scripts from their uploaded URL.


c. Keep the rest of the code the same.


Make sure you remove everything related to the client variable and refresh approach that we defined at first.

You might still get the Error #16 when navigating from a screen that has the gauge chart to another screen that has a normal OutSystems chart, but this error won't have any effect on the loading/rendering of the charts, you can only see it through the console. The loaded Highcharts version will be the same as the one OutSystems Charts is built on, so this wouldn't cause any issues.


I will attach the OML to this reply. Try this approach out and let me know if it works better than the full-page refresh.


Best regards,

Abed

TestCharts.oml
2021-02-16 20-34-58
Remco Snijders
 
MVP

Somehow isHighchartsLoaded returns true for us, even though it is not properly loaded, but removing the condition makes it work! We do indeed get the error #16 in console, but that's not a problem for now. Thanks!

2024-01-04 15-15-51
Abed Al Banna

Hi @Remco Snijders 

I hope you're doing great! I am glad that solution worked for you. 

I just happened to have come across the same issue with another type of charts, and I figured out a way to get rid of the error #16, so I thought of giving you an update. I hope it's not too late!


Instead of the JavaScript code that I had provided earlier:

function isHighchartsLoaded() {

  return typeof Highcharts !== 'undefined';

}

$parameters.IsHighchartsLoaded = isHighchartsLoaded()


Try this code:

function isHighchartsLoaded () {

return Highcharts.version === '10.3.2';

}

$parameters.IsHighchartsLoaded = isHighchartsLoaded ();


The issue with the earlier code is that the typeof Highcharts is always going to return "object" so the condition will always be evaluated as being true.


Given that your Highcharts is normalized to v10.3.2 (the version that OutSystems Charts is using, and the Highcharts v10.3.2 scripts that you downloaded from their website), this should work in all cases.


Best regards,

Abed

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.