Transform JSON into correct format to put in Morris Bar Chart plugin

Linesofcode picture Linesofcode · Jun 19, 2014 · Viewed 12k times · Source

I'm using the Morris Bar Chart plugin. You can see an example here.

The correct data format to insert into the chart is the following:

data: [
    { y: '2006', a: 100, b: 90 },
    { y: '2007', a: 75,  b: 65 },
    { y: '2008', a: 50,  b: 40 },
    { y: '2009', a: 75,  b: 65 },
    { y: '2010', a: 50,  b: 40 },
    { y: '2011', a: 75,  b: 65 },
    { y: '2012', a: 100, b: 90 }
  ],

I want to fill that info but with ajax request to PHP.

$.ajax({
    url: 'getchart.php',
    success: function(content){

        console.log(content); // Native return

        var element = [];   
        var json    = JSON.parse(content);

        for(var i = 0; i <= json.length - 1; i++){
            element[i] = {y: json[i][0].month, a: json[i][0].total};
        }

        console.log(element);
    }
});

I've accomplish the request successfully but I do need to convert the json I get from ajax to the format that morris chart needs.

[[{"total":1,"Month":7,"description":"Started"},
{"total":1,"Month":6,"description":"Started"}],
[{"total":3,"Month":6,"description":"Started"}]] 

The code above is what the variable content output. The problem here is that one index contains 2 sub-indexes and the other index contains only one sub-index:

Index 1:

[{"total":1,"Month":7,"description":"Started"},
 {"total":1,"Month":6,"description":"Started"}],

And the second index only contains one sub-index

Index 2:

[{"total":3,"Month":6,"description":"Started"}]],

This happens because I'm pushing two different arrays into one in PHP.

$AN = $chart->chartAN(); // Apresentation and Negociation
$AC = $chart->chartAC(); // Accomplished

$final = array($AN, $AC);

echo json_encode($final);

And, btw, the output from both of functions is the same:

while($query->fetch()){     
  $rows[] = array("total" => $total, "month" => $month, "description" => $type);
}

Currently, the console.log(element) returns me:

[Object, Object];
    > 0: Object
        a: 1
        y: 7

    > 1: Object
        a: 3
        y: 6

My final result I would like it to be something like:

element: [
          { y: 'April', a: value_from_chartAN, b: value_from_chartAC },
          { y: 'May',   a: value_from_chartAN, b: value_from_chartAC },
         ],

EDIT: To clarify the question (because I know isn't that simple).

I would like my output to be:

element: [
              { y: month_from_database, a: value_from_chartAN, b: value_from_chartAC },
              { y: month_from_database, a: value_from_chartAN, b: value_from_chartAC },
             ],

Since value_from_chartAN or value_from_chartAC might be null, it must add the number 0. If you look at the example of Morris: http://jsbin.com/uzosiq/258/embed?javascript,live

The year correspond to my Month, the blue bar to the value_from_chartAN and the gray bar to value_from_chartAC.

Answer

user1978142 picture user1978142 · Jun 19, 2014

The main problem is that your PHP return values (your JSON that you will send) is not on the same structure as needed by the Bar chart. You need to flatten it first. From there you code should work fine. Sample Fiddle

Consider this example:

<?php
if(isset($_POST['get_values'])) {
    // replication of your data
    $final = '[[{"total":1,"Month":7,"description":"Started"},{"total":1,"Month":6,"description":"Started"}],[{"total":3,"Month":6,"description":"Started"}]]';
    $final = json_decode($final, true);
    $new_final = array();
    // simple flattening
    foreach($final as $value) {
        foreach($value as $sub_value) {
            $new_final[] = $sub_value;
        }
    }

    echo json_encode($new_final);
    exit;
}

?>

<div id="bar-example"></div>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="http://cdn.oesmith.co.uk/morris-0.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){

    $.ajax({
        url: document.URL, // getchart.php
        dataType: 'JSON',
        type: 'POST',
        data: {get_values: true},
        success: function(response) {
            Morris.Bar({
                element: 'bar-example',
                data: response,
                xkey: 'description',
                ykeys: ['Month', 'total'],
                labels: ['Month', 'Total']
            });
        }
    });

});
</script>