ZEE ZEE - 4 months ago 25
Javascript Question

Multiple Highcharts on Primefaces single page, gives javascript error

I am using Highcharts 4.2.5 to display graphs in my Primefaces 6.0 application, which runs on (JSF 2.0, Java 7, Weblogic 11g).

I have a requirement where i need to show multiple dynamic graphs on a single page. The graphs are not hardcoded on the page. Infact they need to be rendered on the fly based on users privileges. One user can see 1 graphs, whereas other can see multiple graphs on the same page.

My problem is that ,the jsonpCallback function which i want to get called for each graphs seperately, DOES NOT get called successfully, due to some parser error on the jsonp data.

Strange thing is that, sometimes it gets called for some graph, but after subsequent page refresh, it gives a parser error. Below is my JSF xhtml code / JS Code / and the browser console log. The below use case is of 2 graphs, but only one graph renders correctly, and other gives parser


  1. XHTML CODE.

    <ui:repeat var="c" value="#{cg.charts}" varStatus="status">
    <div class="Container25 Responsive NoIndent">
    <div class="EmptyBox20"></div>

    <p:panel style="min-height: 300px;">
    <div class="Container" >
    <!--<i class="icon-chart-bar Fs30 Fleft Wid25 red TexAlCenter" ></i>-->
    <div id="chartContainer#{c.id}"></div>
    <script type="text/javascript">
    generateMLChart('chartContainer#{c.id}');
    </script>
    </div>
    </p:panel>

    </div>
    </ui:repeat>

  2. Javascript Code

    function generateMLChart(divId){
    console.log('generateMLChart called... '+divId);
    chartType="prepareMLChartOptions";

    $.ajax({
    type: "GET",
    url:"./multilinechartservlet/"+Math.random()+"?jsonp="+chartType,
    dataType: 'jsonp',
    jsonpCallback: chartType, // the function to call
    success: function(json) {
    console.log("divId = "+divId);

    var len = json.multilinedata.length;
    //var divid = json.divid;
    i = 0;

    // setting options variable
    var options = {
    credits: {
    enabled: false
    },
    rangeSelector: {
    allButtonsEnabled: true
    },
    legend:{
    enabled: true
    },
    title:{
    text : 'Key Policy Interest Rates'
    },

    series: []
    }

    // setting options.series variable with json data, it should be a loop coz, it can have multiple series.
    for (i; i < len; i++) {
    options.series.push(json.multilinedata[i]);
    }

    // finally populate the charts container
    $('#'+divId).highcharts("StockChart",options);

    console.log('success function - complete');
    },
    error: function(xhr, status, error) {
    alert(error);
    console.log("xhr.responseText ="+xhr.responseText);
    console.log("status="+status);
    console.log("error="+error);
    }
    });

    }

    function prepareMLChartOptions(json,divId) {

    if(divId == undefined)
    return;

    }

  3. Chrome console log




status=parsererror multilinechart.js:49

error=Error: prepareMLChartOptions was not called

ZEE ZEE
Answer

I resolved, it by using tweaking my generateMLChart() function and using $.getJSON instead of $.ajax, and in $.getJSON, the call back function is a dynamic one, and not a static function.

    function generateMLChart(divId,
                    chartName,
                    chartId,
                    qNo) {
console.log('generateMLChart called... ' + divId+ ' - '+ chartName + ' - '+qNo);

$.getJSON("./chartservlet?chartId=" + divId + "&queryNumber=" + qNo, function (data, textStatus, jqxhr) {
    console.log("textStatus = " + textStatus);// Success
    console.log("jqxhr.status =" + jqxhr.status);// 200
    console.log("divId = " + divId);


    var len = data.multilinedata.length;
    i = 0;

    // setting options variable
    var options = {
        credits :  {
            enabled : false
        },
        rangeSelector :  {
            allButtonsEnabled : true
        },
        legend :  {
            enabled : true
        },
        title :  {
            text : chartName
        },
        series : []
    }

    // setting options.series variable with json data, it should be a loop coz, it can have multiple series.
    for (i;i < len;i++) {
        options.series.push(data.multilinedata[i]);
    }

    // finally populate the charts container
    $('#' + divId).highcharts("StockChart", options);

    console.log('-- success function - complete');

}).fail(function (jqxhr, settings, exception) {
    console.error("exception =" + exception);
    console.log("jqxhr =" + jqxhr);
    console.log("settings =" + settings);
    alert("Triggered ajaxError handler. Contact IT- Helpdesk");
});

    }