March 24, 2012

Generate a highchart based on the output of an array

Question by php_d

UPDATE I have updated my code in response to @MichaelRushton comments. I am now using Highcharts but I am having trouble getting output to the data series.

I now have the following array generated from a mysql query, and I would like to output it into a line chart. My Y-Axis should contain the amount, x-axis is the date range, and legend is the different items plotted on the chart.

   // Call the stored procedure
   $stmt->execute();                    

   while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
       $array[$row['legend']][$row['date']] = $row['amount'];
       //print_r($array);
   }


   chart = new Highcharts.Chart({

   chart: {
     renderTo: 'container',
     type: 'line'
   },

   xAxis:
   {
    categories: [2012-03-01, 2012-03-02, 2012-03-03, 2012-03-04, 2012-03-05, 2012-03-06, 2012-03-07, 2012-03-08, 2012-03-09, 2012-03-10, 2012-03-11, 2012-03-12, 2012-03-13, 2012-03-14, 2012-03-15, 2012-03-16, 2012-03-17, 2012-03-18, 2012-03-19, 2012-03-20, 2012-03-21, 2012-03-22, 2012-03-23, 2012-03-24, 2012-03-25, 2012-03-26, 2012-03-27, 2012-03-28, 2012-03-29, 2012-03-30, 2012-03-31],
   },

   series:
   [

<?php
     foreach ($array as $legend => $data)
         {
           echo '{';
           echo "name: '" . $legend . "',";

           $values = array();

           for ($i = 1; $i <= 31; ++$i)
           {
             $values[] = isset($data[$i]) ? $data[$i] : 0;
           }

           echo 'data: [' . implode(', ', $values) . '],';
           echo '},';

         }
?>
],
 }
 );

<div id="container" style="width: 100%; height: 400px"></div>
) 

This code is presenting me with the following output:

series: [ {name: 'Something Tastier',data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],},{name: 'Something Tasty',data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],}, ], } );

The seems right except there is no values outputting to the data series. If anyone has any further ideas it would be much appreciated.

Answer by MichaelRushton

Highcharts is my favourite option for graphs. It might be worth structuring your array to look like:

Array (

  [legend_one] => Array
  (

    [2012-03-01] => 100
    [2012-03-02] => 200
    [2012-03-03] => 300
    ...

  )

  [legend_two] => Array
  (

    // Day of the month    
    [2012-03-01] => 100
    [2012-03-02] => 200
    [2012-03-03] => 300
    ...

  )

  ...

)

You can then use Highcharts like this:

Edit: Now uses full date rather than just day, made the month dynamic (using $start variable), and started the day iterator at 0 rather than 1 to remove the need for $i - 1 when using strtotime to work out the next date.

chart = new Highcharts.Chart({

  xAxis:
  {

    categories: [

<?php

      // You could dynamically set this date using $_GET/$_POST
      $start = '2012-03-01';

      $dates = array();

      for ($i = 0, $days = date('t', strtotime($start)); $i < $days; ++$i)
      {
        $dates[] = date('Y-m-d', strtotime($start . ' + ' . $i . ' day'));
      }

      echo "'" . implode("', '", $dates) . "'";

?>

    ],

  },

  series:
  [

<?php

    foreach ($array as $legend => $data)
    {

      echo '{';

      echo "name: '" . $legend . "',";

      $values = array();

      for ($i = 0; $i < $days; ++$i)
      {

        $date = date('Y-m-d', strtotime($start . ' + ' . $i . ' day'));

        $values[] = isset($data[$date]) ? $data[$date] : 0;

      }

      echo 'data: [' . implode(', ', $values) . '],';

      echo '},';

    }

?>

  ],

}
);

Answer by Starx

You are going the wrong way. If you searching for something that is already available, then you should output the data in the way, they accept. Not the other way around.

With that being said, try pChart. It has wide support for different formats.

...

Please fill the form - I will response as fast as I can!