2

Am trying to generate multiple line charts at one go using the code below. However, it isn't working. What would be the best way to generate graphs using a for/while or any other looping mechanism? I have many charts to generate.

   var db_query = Array();
    db_query[1] = <?php echo json_encode($db_query_1) ?>;
    db_query[2] = <?php echo json_encode($db_query_2) ?>;

    var chartConfig1 = clone(chartConfigLineOne);
    var chartConfig2 = clone(chartConfigLineOne);

    for(var i=1, len=2; i <= len; i++) {
        /* chart initialization */
        var chart_num = "chart" + i.toString();
        var plot_num =  "plot" + i.toString();
        var chartConfig_num = "chartConfig" + i.toString();
        /*alert(chart_num);
        alert(plot_num);
        alert(chartConfig_num);*/
        chart_num = AmCharts.makeChart(plot_num, chartConfig_num);

        $.ajax({
            type: 'POST',
            url: "query_db.php",
            data: {'db_que': db_query[i]},
            dataType: 'json',
            context: document.body,
            global: false,
            async:  true,
            success: function(data) {
                //alert(data);
                chart_num.dataProvider = data;
                chart_num.validateNow();
            }
        });
    }

UPDATED CODE

        <script type="text/javascript">

            var chartNameList = ['chart1','chart2'];
            var divId = ['plot1','plot2'];
            var configList = ['chartConfig1','chartConfig2'];
            var dbQuery = [];

            var chartConfig1 = clone(chartConfigLineOne);
            var chartConfig2 = clone(chartConfigLineOne);

             dbQuery[0] = <?php echo json_encode($db_query_1) ?>;
             dbQuery[1] = <?php echo json_encode($db_query_2) ?>;

            /* chart initialization */
            for(var i =0; i < 2; i += 1)   {
                //window["chart"+i] = createChartObj(divId[i],configList[i]);
                execDbQuery(divId[i],configList[i],dbQuery[i],chartNameList[i]);
            }
        </script>

/**
 * Execute of DB query
 */

function execDbQuery(divId, configObj, dbQuery, chartObj) {
    chartObj = AmCharts.makeChart(divId, configObj);
    $.ajax({
        type: 'POST',
        url: "query_db.php",
        data: {'db_que': dbQuery},
        dataType: 'json',
        context: document.body,
        global: false,
        async:  true,
        success: function(data) {
            //alert(data);
            chartObj.dataProvider = data;
            chartObj.validateNow();
        }
    });
} 
10
  • Don't mix JavaScript with PHP like db_query[1] = <?php echo json_encode($db_query_1) ?>;. It is terribly awful. And try not to use multiple var a; var b; var c;, but instead just use var a = 123, b = 345, .... If you don't change your style of programming, some day your code will look like spagetti. Commented Aug 29, 2015 at 21:24
  • And instead of alerting, like alert(data) use console.log(data). The style you are programming has become obsolete several years ago. So, you'd better read some books about professional programming in JavaScript. Commented Aug 29, 2015 at 21:27
  • Hello Jacobian - Thank you for the directions. Am a newbie in programming. THere's definitely a steep learning curve. Could I request your help to understand how to do what I'm trying to achieve? Also, if you could quickly brief me on how to access PHP data inside a javascript or another way of doing that altogether, that would be really helpful Commented Aug 29, 2015 at 21:31
  • You already know how to access PHP data inside Javascript. This is actually what ajax does in your example. Commented Aug 29, 2015 at 21:33
  • Taking one step back, I have a main page where user chooses values. Then upon clicking submit, those values get posted to a PHP page where a SQL is constructed dynamically ( The receiving of data posed & building SQL query happens between <?php ... ?> section. After this section, I have a javascript section inside which I have ajax code. So, to access the SQL built int he PHP code, am using db_query[1] = <?php echo json_encode($db_query_1) ?> Could you suggest a different way of doing this altogether please? Commented Aug 29, 2015 at 21:39

2 Answers 2

2

As many comments correctly pointed out, you should probably start with rethinking your approach to data loading. Passing SQL queries in from client-side is asking for trouble. Will you be able to properly sanitize your queries to guard against malicious code? You can't be sure.

It's far more reasonable to move your DB access layer to PHP. You can pass in parameters needed for PHP script running on server to identify what needs to be loaded from DB and construct and execute actual SQL queries.

I.e.: query_db.php?chart_id=5

It would be up for PHP script to determine what to do. Given that you're currently using PHP to format those SQL queries, I can hardly image it can be a problem.

This brings us to another issue. Your current setup will run multiple AJAX requests simultaneously. While it's probably OK in the example you posted which has two charts, it can bog down the performance if you you have, say, 30 charts you need to load data for.

The solution would be to daisy-chain the loading. Do not start loading of another chart, until the previous one finishes loading. I.e.:

var charts = [ {
  "name": "chart1",
  "div": "plot1",
  "config": clone( chartConfigLineOne ),
  "query": <? php echo json_encode( $db_query_1 ) ?>
}, {
  "name": "chart2",
  "div": "plot2",
  "config": clone( chartConfigLineOne ),
  "query": <? php echo json_encode( $db_query_2 ) ?>
} ];

// do whatever modifications to each chart's config you need here
// ...

// function that creates the chart
function processNextChart() {
  if ( charts.length ) {
    var chart = charts.shift();
    $.ajax( {
      type: 'POST',
      url: "query_db.php",
      data: {
        'db_que': chart.query
      },
      dataType: 'json',
      context: document.body,
      global: false,
      async: true,
      success: function( data ) {
        chart.config.dataProvider = data;
        chartObj = AmCharts.makeChart( chart.div, chart.config );
        setTimeout( processNextChart, 100 );
      }
    } );
  }
}

// process first chart
processNextChart();

Please note how I simplified your whole chart array with a single array that holds all applicable data.

Please note, that the above code is not live-tested and is meant as a guiding point for your own implementation.

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you very much Martyn. I appreciate your help very much. I'm learning a whole new way of doing things. Thank you for this. With reference to passing SQL queries around, i don't pass them from client/browser to PHP. I only pass things such as date range & option selected & post it to PHP which builds the SQL & executes it via ajax & plots the graph. To clarify, if I did a "view page source" or used to tools such as firebug, I wouldn't be able to see any SQL. I'll refer to your example & implement. Will let you know how I get on soon.
Definitely. Just made some updates to the code. (noticed a bug)
Hello Martyn - Could you please accept the "Edit". I've changed the sql query name for consistency.
It was rejected by other editors before I could get to it. So I just made the same edits myself.
Thank you Martin. Alongside this, I managed to create 3 layers of hierarchy. A layer where user input is taken, a layer where PHP receives the user input & makes ajax call to another layer where PHP builds the SQL, executes & returns a jSON array back to layer 2 which plots the graphs. Does this sound a good/better way of doing things?
|
0

Do not make ajax calls inside the for loop. It's a burden on server. The less calls you make, the more responsive is your ui. So, the better way to implement what you want is to get all data for all graphs in one ajax call and on success to iterate through the data building your graphs with AmCharts.makeChart.

4 Comments

I would love to implement it the way you suggest. Unfortunately, the SQL queries are all different ( They return different number of columns). That's why I'm after looping :-(
Move this database logic to the server side.
I mean I have a bunch of SQL queries that I execute one after another & plot graphs for each of those query results. The SQL output has different number of columns. Example, Date, COUNT(A) as output of first SQL, DATE,COUNT(C) for 2nd, DATE, NAME, COUNT(F) for 3rd and many more combinations.
I know this is not related to the question. But I just could not ignore the user: gerric's willingness to help User12345. Really awesome to see such a good coding community. Gerric started to help him out in this thread, stackoverflow.com/questions/32256442/… and I followed the rabbit hole till here.. Awesome

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.