morris chart not updating

2019-08-07 09:42发布

I have a problem with updating my morris.js bar chart.

When the page loads, I have the following function, which works fine and creates a nice chart:

$(document).ready(function() {
    if($('.projectViewTotal').length) {
        chart = Morris.Bar({
          element: 'LastIncome',
          data: [
              { y: '04-02-2014', a: 3 },
              { y: '04-03-2014', a: 10 },
              { y: '04-04-2014', a: 5 },
              { y: '04-05-2014', a: 17 },
              { y: '04-06-2014', a: 6 }
            ],
          xkey: 'y',
          ykeys: ['a'],
          labels: ['Visits']
        });
    };
});

Then after some user action I get new data via ajax and want to update my chart, but unfortunately after the update no data is shown in the chart and the labels are just undefined. I also get no error via the console.

and then I update the chart like this:

var response = $.parseJSON(content);
console.log(response);
chart.setData(response.jsString);

When I console.log my ajax answer I have this data structure for example:

Object {jsString: "[ { y: '2014', a: 3505},{ y: '2013', a: 0},{ y: '2012', a: 0},{ y: '2011', a: 0} ]", sort: "getLastIncome"}

But as I said I just get undefined labels and a chart with no data inside.

If I use chart.setData() width hard coded sample data everything also works fine. So it must be with the string I get from response.jsString, but I already used $.parseJSON on the callback, so I really don't know where the problem might be.

Do you have any ideas where the error might be? Thank you!

Here is my server side php code:

$ausgabeJS = "[ ";
$amount = count($data);
$i = 1;
foreach ($data as $key => $value) {
    if($i < $amount) {
       $ausgabeJS .= "{ y: '".$key."', a: ".$value."},";
    } else {
       $ausgabeJS .= "{ y: '".$key."', a: ".$value."}";
    }
    $i++;
}
$ausgabeJS .= " ]";
$responseArray = array(
   "jsString" => $ausgabeJS,
   "sort" => $method
 );
$result = json_encode($responseArray);

SOLUTION

Like JTG suggested, I had to change my server side code, to create a numeric array instead of a string. Here is the updated code:

$data_array = array();
foreach ($data as $key => $value) {
   $ar = array(
      "y" => $key,
      "a" => $value
   );
   array_push($data_array, $ar);
}
$responseArray = array(
   "jsString" => $data_array,
   "sort" => $method
);
$result = json_encode($responseArray);

1条回答
走好不送
2楼-- · 2019-08-07 10:08

Your response.jsString is still a string, which isn't the accepted parameter for the setData function (it has to be an array of hash arrays).

Unfortunately, you can't JSON parse the jsString string because your keys aren't strings (which is a requirement for JSON) So make your keys strings, like so on your server side

{jsString: '[{"y": "2014", "a":2505}, {"y": "2014", "a":2505}, {"y": "2014", "a":2505}]', sort: "getLastIncome"}

And then you should be able to add the data to your graph

chart.setData($.parseJSON(response.jsString));

Let me know if that doesn't work

EDIT: Okay so we have two options.

First, you could change your php code to be

$data_return = [];
foreach ($data as $key => $value) {
    array_push($data_return, array("y" => $key, "a" => $value));
}

$responseArray = array(
   "jsString" => $data_return,
   "sort" => $method
 );
$result = json_encode($responseArray);

I'm not certain this will work, I think it's worth a try because you aren't building a string that will have to be parsed twice.

But if that doesn't work, you can always go with my original suggestion and turn the keys of your hash array into strings themselves like so:

foreach ($data as $key => $value) {
    if($i < $amount) {
       $ausgabeJS .= "{ 'y': '".$key."', 'a': ".$value."},";
    } else {
       $ausgabeJS .= "{ 'y': '".$key."', 'a': ".$value."}";
    }
    $i++;
}

notice the extra single string quotes around the y and a. Now the string you are building is proper JSON. Now you should be able to do this.

var response = $.parseJSON(content);
console.log(response);
chart.setData($parseJSON(response.jsString));
查看更多
登录 后发表回答