Search code examples
javascriptjqueryjsonajaxmorris.js

Data from JQUERY/AJAX to Morris.JS


I'm trying to export data from AJAX/JQUERY to Morris.JS.

Variable datachart return with data. but morris.js graph returns no Line/bar

            $("#diseaseselection").change(function(){
                $("#chart").empty();
                var diseaseselection = $("#diseaseselection").val();
                $.ajax({
                    url: "chart.php",
                    method: "POST",                   
                    data: {
                        diseaseselection: diseaseselection
                    },
                    success: function(data) {
                        Morris.Line({
                            element : 'chart',
                            data:[data],
                            xkey:'age',
                            ykeys:[ 'totalM', 'totalF'],
                            labels:['Total MALE', 'Total FEMALE'],
                            hideHover:'auto',
                            pointStrokeColors: ['white'],
                            lineWidth:'6px',
                            parseTime: false,
                            lineColors: ['Skyblue', 'Pink'],
                        });
                    }

                });
            });

Here is my sample PHP code Please help me how to figure it out i badly need it thanks alot man. already trying my best

$diseaseselection = $_REQUEST['diseaseselection'];

if(isset($diseaseselection)){ 
   $result = mysqli_query($con, "SELECT disease,age,SUM(CASE WHEN gender = 'm' THEN 1 ELSE 0 END) AS totalM, SUM(CASE WHEN gender = 'f' THEN 1 ELSE 0 END) AS totalF FROM mdr where disease = '$diseaseselection' GROUP BY disease , age"); 
   $chart_data = ''; 

while($row = mysqli_fetch_array($result)) { 
      $chart_data .= "{ age:'".$row["age"]."', totalM:".$row["totalM"].", totalF:".$row["totalF"]."}, "; 
} 
$chart_data = substr($chart_data, 0, -2); 
echo $chart_data; }

Here is my sample Output This is based on my console log console.log(data); Please help me how to figure it out i badly need it thanks alot man. already trying my best

{ age:'0-1', totalM:2, totalF:1},

{ age:'1-4', totalM:1, totalF:0},

{ age:'10-14', totalM:0, totalF:1},

{ age:'15-19', totalM:0, totalF:1},

{ age:'5-9', totalM:0, totalF:3},

{ age:'55-59', totalM:6, totalF:0}

Solution

  • There are a number of little issues here, which are kind of all tied up in the same key problem - what your PHP is producing is not valid JSON data.

    If you copy and paste your sample data into a validator such as JSONLint you'll that it fails in a couple of ways:

    1) You've got a list of objects, but in order to be a valid list (or array, as it's usually known) the items must be wrapped in square brackets ([ and ]) at the beginning and end.

    2) The property names (e.g. age, totalM, and totalF) must have double quote marks (") around them.

    3) The string values (e.g. 0-1, 1-4 etc) must have double quote marks around them, not single quote marks.

    A valid version of your sample JSON would look like this:

    [
      { "age": "0-1", "totalM": 2, "totalF": 1 }, 
      { "age": "1-4", "totalM": 1, "totalF": 0 }, 
      { "age": "10-14", "totalM": 0, "totalF": 1 }, 
      { "age": "15-19", "totalM": 0, "totalF": 1 }, 
      { "age": "5-9", "totalM": 0, "totalF": 3 }, 
      { "age": "55-59", "totalM": 6, "totalF": 0 }
    ]
    

    You might find this tutorial useful as a quick way to learn the syntax.

    However, useful as it is to know the syntax, you don't actually have to create it manually via your PHP, as you are doing now. In fact that's quite a bad idea to do that, because it leaves you vulnerable to silly mistakes (like not adding the square brackets), and at risk of accidental syntax errors in the JSON (e.g. imagine one of your string values itself contained a double-quote mark: if you didn't use a suitable escape character in front of it, then in the JSON it would look like the end of the property, and what followed would then be invalid).

    The result of the problems above is that your PHP returns a string of invalid data back to the browser, and that cannot be used to populate the chart.

    It's far better to simply construct a normal array in PHP, and then use the built-in json_encode() function to take care of turning that object into valid JSON. This is commonly accepted as best practice, and if you follow any introductory PHP/JSON tutorial it will show this function to you.

    To add to the problems creating the JSON server-side, there's a client-side issue too: even if you did return valid JSON, at that point it's still a string - in order for it to be used in your chart you'd have to parse it into a JavaScript variable. If you specify dataType: "json" in your $.ajax options, jQuery will do the parsing for you automatically. Otherwise, you would make a call to JSON.parse() to do it.

    Hopefully you see the overall pattern now - you take a PHP variable and turn it into JSON, which is a text representation of the data. This allows you to send it across the internet. Then when it arrives at the destination, you turn it back into a (JavaScript) variable again to be used in the code.

    Here's some example PHP which will generate valid JSON in the recommended way. I've added comments at important lines:

    $diseaseselection = $_REQUEST['diseaseselection'];
    
    if(isset($diseaseselection)){ 
       $result = mysqli_query($con, "SELECT disease,age,SUM(CASE WHEN gender = 'm' THEN 1 ELSE 0 END) AS totalM, SUM(CASE WHEN gender = 'f' THEN 1 ELSE 0 END) AS totalF FROM mdr where disease = '$diseaseselection' GROUP BY disease , age"); 
       $chart_data = array(); //declare an array, not a string. This will become the outer array of the JSON.
    
      while($row = mysqli_fetch_array($result)) { 
          //add a new item to the array
          //each new item is an associative array with key-value pairs - this will become an object in the JSON
          $chart_data [] = array(
            "age" => $row["age"], 
            "totalM" => $row["totalM"], 
            "totalF" => $row["totalF"]
          ); 
      } 
    
      $json = json_encode($chart_data);  //encode the array into a valid JSON object
      echo $json; //output the JSON
    }
    

    And here's the relevant part of the JavaScript code to receive it

    $.ajax({
      url: "chart.php",
      method: "POST",
      data: {
        diseaseselection: diseaseselection
      },
      dataType: "json", //parse the response data as JSON automatically
      success: function(data) {
        Morris.Line({
          element: 'chart',
          data: data, //supply the response data (which is now a JS variable) directly, no extra brackets
          xkey: 'age',
          ykeys: ['totalM', 'totalF'],
          labels: ['Total MALE', 'Total FEMALE'],
          hideHover: 'auto',
          pointStrokeColors: ['white'],
          lineWidth: '6px',
          parseTime: false,
          lineColors: ['Skyblue', 'Pink'],
        });
      }
    });
    

    Here's a working demo of just the AJAX and chart part (using a dummy server to provide the JSON): https://jsfiddle.net/7o9ptajr/1/