最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Transform JSON into correct format to put in Morris Bar Chart plugin - Stack Overflow

programmeradmin8浏览0评论

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 acplish 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(); // Acplished

$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: ,live

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

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 acplish 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(); // Acplished

$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./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.

Share Improve this question edited Jun 19, 2014 at 11:14 Linesofcode asked Jun 19, 2014 at 10:36 LinesofcodeLinesofcode 5,92314 gold badges71 silver badges131 bronze badges 4
  • To flatten the returned json array in the browser -- to get rid of the two index problem -- see: stackoverflow./questions/10865025/… – Paul Commented Jun 19, 2014 at 10:43
  • I dont see where the value for b: in your expected output is supposed to e from, and the value for y: should logically be a year (2014) yet you want it to be a month (April)? Please edit you question to clarify – Steve Commented Jun 19, 2014 at 11:01
  • I've just updated my topic. – Linesofcode Commented Jun 19, 2014 at 11:14
  • 1 @user3355243 OK, ill update my answer with a solution – Steve Commented Jun 19, 2014 at 12:12
Add a ment  | 

3 Answers 3

Reset to default 3

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./ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare./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> 

You control the data sent from the server, so make sure its in the correct format before sending it - simply merge the php arrays into one, and set the correct header:

$final = array_merge($AN, $AC);
header('Content-Type: application/json');
echo json_encode($final);

Now you have the exact format you require returned to your ajax function, no further js processing required:

$.ajax({
    url: 'getchart.php',
    success: function(content){
        console.log(content); // Native return is as required

    }
});

EDIT as per your clarification. The solution is still to send the correct data from php, but the code is a little more plicated:

//simulated calls to your functions, based on your posted data
$an = json_decode('[{"total":1,"Month":7,"description":"Started"}, {"total":1,"Month":6,"description":"Started"}]', true);
$ac = json_decode('[{"total":3,"Month":6,"description":"Started"}]', true);


//1st create an array from the $ac data that uses the month value as the key, 
//so we can check if  any month is contained in the array simply:    
$ac_new=array();
foreach($ac as $item){
    $month = $item['Month'];
    $ac_new[$month] = $item['total'];
}
//array to hold are final data
$data = array();

foreach($an as $item){
    $y = $item['Month'];
    $a = $item['total'];

    //if there is a value for this month in ac_new array, set $b to its value
    //and then remove the element from the ac_new array, else set $b = 0
    if(isset($ac_new[$y])){
        $b = $ac_new[$y];
        unset($ac_new[$y]);
    }else{
        $b = 0;
    }
    $data[] = array('y' => $y, 'a' => $a, 'b' => $b);
}

//if there any elements left in $ac_new then they are for months 
//not included in $an array, so value for a must be 0
if(count($ac_new)>0){
    foreach($ac_new as $key => $value){
        $data[] = array('y' => $key, 'a' => 0, 'b' => $value);
    }
}

//return correctly formatted data
header('Content-Type: application/json');    
echo json_encode($data);
<?php
session_start();

include("../phpfiles/include/Config.php"); //db connect


$dbc = @mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD,DB_DATABASE);

if(!$dbc)
{
    trigger_error('Could not connect to MySql:'. mysqli_connect_error());
}
$query = "SELECT dateandtime,sum(grandtotal) FROM bb_pos.bb_bill
group by MONTH(dateandtime), YEAR(dateandtime) order by dateandtime DESC limit 12 "; // last 12 month in descending order
$result = mysqli_query($dbc, $query);
$cart = array();
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC))
{
    $date = $row['dateandtime'];
    $time=strtotime($date);
    $month=date("F",$time);
    $year=date("Y",$time);
    array_push($cart,array(
    'period'=>$month." ".$year,
    'SALE'=>$row['sum(grandtotal)']));

}

echo json_encode($cart);
mysqli_close($dbc);
?>  

<body>
<div class="x_content1">
   <div id="graph_bar_group" style="width:100%; height:280px;"></div>
</div>
</body>
<script>
$.getJSON('morrisdata.php', function(data) 
    {
        var date = data;
        function custom_sort(a, b) {
        return new Date(a.period).getTime() - new Date(b.period).getTime();
        }   
        date.sort(custom_sort); // convert the last 12 months in ascending order

    //var product_name = data.name;
        Morris.Bar({
            element: 'graph_bar_group',
            data: data,
            xkey: ['period'],
            ykeys: ['SALE'],
            labels: ['SALE'],
            hideHover: 'auto',
            resize: true,
            parseTime: false,
            xLabelAngle: 60

        });
    });

</script>
发布评论

评论列表(0)

  1. 暂无评论