2

I have a Salesforce Lightning customer community and I have several lightning components with different charts and maps using Highcharts and the map.js module.

I have the following code.

Map component

<ltng:require scripts="/resource/jquery,
                       /resource/HighCharts, 
                       /resource/HCMap, 
                       /resource/HCData" afterScriptsLoaded="{!c.jsLoaded}" />

Chart component

<ltng:require scripts="/resource/jQuery,
                       /resource/HighCharts,
                       /resource/HCModuleExporting,
                       /resource/HCNoData" afterScriptsLoaded="{!c.doInit}" />

The problem comes when the Map component tries to load the resource HCMap (which is Map.js from Highcharts). It throws Highcharts #16 error and Map component does not load.

From Highcharts API:

Highcharts Error #16

Highcharts already defined in the page

This error happens the second time Highcharts or Highstock is loaded in the same page, so the Highcharts namespace is already defined. Keep in mind that the Highcharts.Chart constructor and all features of Highcharts are included in Highstock, so if you are running Chart and StockChart in combination, you only need to load the highstock.js file.

As you can see I am requiring the same Highcharts for both components but the error is still there.

I guess it is related to Lightning creating one instance of a static resource.

I tried using Highmaps directly but I face the same error and the manufacturer does not recommend it so I switched to Highcharts + Map.js highcharts module.

Is there any workaround for this?

2 Answers 2

5

I uploaded a simple example of the correct way to use Highstock with LC - their instructions about how to load both Highcharts and Highmaps seems to be confusing (the section about loading both highstock and highmaps).

https://login.salesforce.com/packaging/installPackage.apexp?p0=04tj0000001udTg

The example shows multiple instances of c:highChartDemo and c:highMapsDemo components being used in the same .app without issue.

You can see the approach I've used without installing the package:

  • create 2 Static Resources from the downloaded ZIPs of Highstock and HighMaps (downloaded from Highstock 4.2.3 and Highmaps 4.2.3)
  • create 2 LCs, one for a simple Map and the other for a Chart (source code directly from the examples on Highcharts.com)

highChartDemo.cmp:

<aura:component>
    <ltng:require scripts="/resource/highstock_4_2_3/js/highstock-all.js, /resource/highmaps_4_2_3/js/modules/map.js"
            afterScriptsLoaded="{!c.afterScriptsLoaded}"/>
    <div aura:id="chart" style="width:100%; height:400px;"/>
</aura:component>

highChartDemoController.js:

({
    afterScriptsLoaded: function(component, event, helper) {
        var chart = new Highcharts.StockChart({
            chart: {
                renderTo: component.find("chart").getElement(),
                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]
            }]
        });
    }
})

highMapDemo.cmp:

<aura:component>
    <ltng:require scripts="/resource/highstock_4_2_3/js/highstock-all.js, /resource/highmaps_4_2_3/js/modules/map.js"
        afterScriptsLoaded="{!c.afterScriptsLoaded}"/>
    <div aura:id="map" style="width:100%; height:400px;"/>
</aura:component>

highMapDemoController.js:

({
    afterScriptsLoaded: function(component, event, helper) {
        var map = new Highcharts.Map({
            chart: {
                renderTo: component.find("map").getElement()
            },
            series: [{
                "type": "map",
                "data": [{
                    "name": "g3776",
                    "path": "M343,-165,342,-150,359,-130,356,-115,381,-91,397,-92,422,-113,428,-162,395,-157,372,-158,343,-165zM419,-192,425,-175,434,-169,440,-182,419,-192z"
                }, {
                    "name": "Western Australia",
                    "path": "M10,-547,84,-595,145,-602,195,-616,238,-694,302,-742,343,-769,391,-737,391,-302,317,-282,264,-263,253,-245,166,-240,112,-213L67,-214,41,-245,60,-266,55,-314,45,-332,0,-442,24,-452,2,-501z"
                }, {
                    "name": "Northern Territory",
                    "path": "M486,-823,467,-809,431,-802,412,-768,391,-737,391,-447,616,-449,616,-697,553,-742,586,-809z"
                }, {
                    "name": "Queensland",
                    "path": "M616,-695,662,-666,693,-687,707,-735,710,-814,728,-849,759,-751,779,-756,802,-726,821,-637,884,-599,909,-540,936,-537,950,-504,981,-468,1000,-387,967,-385,953,-368,936,-380,903,-383,895,-373,693,-373,693,-447,616,-451z"
                }, {
                    "name": "New South Wales",
                    "path": "M917,-147,929,-209,960,-261,991,-304,1000,-387,964,-380,955,-370,936,-380,907,-383,895,-373,693,-373,690,-240,729,-228,750,-223,788,-182,800,-194,871,-183,876,-161z"
                }, {
                    "name": "path3788",
                    "path": "M883,-204,903,-183,910,-199,893,-211z"
                }, {
                    "name": "Victoria",
                    "path": "M391,-304,455,-302,519,-271,557,-218,616,-269,605,-235,583,-201,612,-202,622,-223,628,-197,648,-192,688,-130,690,-240,693,-447,614,-449,391,-451z"
                }, {
                    "name": "Victoria",
                    "path": "M817,-113,855,-125,917,-147,876,-161,869,-183,800,-194,788,-182,748,-223,690,-249,688,-130,752,-116,786,-132z"
                }]
            }, {
                "type": "mapline",
                "data": [{
                    "name": "path3790",
                    "path": "M243,-168,316,-240,457,-238,540,-152,540,-152"
                }]
            }]
        });
    }
})
6
  • I tried the solution you propose but I still get the error. The implementation is very similar to yours but instead of Highstocks I am using Highcharts. The only difference is the way I invoke Highcharts. I create the chart as a callback of a jQuery function which retrieves a geoJSON file from my Static Resources. Commented Apr 12, 2016 at 14:17
  • @DavidCarnicerdid you try it just like I presented above though before deviating? Worked for me right out of the box - Highstock includes high charts etc. Before trying to subset things or use their builder to get the smallest build possible I'd recommend starting simple lie I have above. Commented Apr 12, 2016 at 20:51
  • I still get the error. Extensible Chart: <aura:component extensible="true" abstract="true" controller="ChartsDispatcher"> <ltng:require scripts="/resource/jQuery,/resource/Highstock/js/highstock-all.js,/resource/Highmaps/js/modules/map.js" afterScriptsLoaded="{!c.doInit}" /> </aura:component> Commented Apr 13, 2016 at 10:46
  • Map component: <aura:component controller="MapController" implements="forceCommunity:availableForAllPageTypes" access="global"> <ltng:require scripts="/resource/jquery, /resource/Highstock/js/highstock-all.js, /resource/Highmaps/js/modules/map.js, /resource/HCData" afterScriptsLoaded="{!c.jsLoaded}" /> <aura:handler event="c:event_OnAcceptFiltersMapa" action="{!c.filtrarMapa}" /> <div id="containerProvincia"></div> </aura:component> Commented Apr 13, 2016 at 10:49
  • finally I solved it. I work with Sublime and MavensMate and someone in my org was overwriting my code with the solution you proposed. Now it works perfectly! Thank you!! Commented Apr 13, 2016 at 15:04
1

I do not think this is an ltng:require or lightning components specific issue - if anything ltng:require's once and only once loading semantics should help not hurt. All ltng:require does is dynamically create a series of script elements using document.createElement("script") in the same way that other script loading libraries like requirejs do. The component first checks to see if the DOM already contains the script tag it is about to create and skips that phase if one already exists. It's possible that there is some interleaving that is tripping things up but that has automated tests already and has been working well to date so I am inclined to first suspect the overlap in the libraries above.

The issue looks to me as a more general challenge with dynamically loading these resources into a single page application architecture environment in general. Many libraries were just not designed with this in mind - they grew up in a full page navigation, statically loaded, single author world.

Do you see this error if you simply include 2 instances of just the map component in a trivial .app?

2
  • Thanks for your explanation, Doug. I still see this error when I include those components in an app: "Looks like there's a problem: Uncaught Error: Highcharts error #16: www.highcharts.com/errors/16" Commented Apr 6, 2016 at 11:41
  • 1
    Any new updates on this? keeping in mind of the LockerService also? We are also facing similar issue. In out case the we have used same component that refers HighCharts in two different Lightning Pages. While switching to another from the first one in Salesforce1 Navigation menu, it is throwing this Error #16. On first load it works fine. but not able to switch between tabs. Commented Jun 22, 2016 at 9:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .