Activehighcharts Timedate With Irregular Time Intervals

I am trying to create a bytes(y) vs time(x) chart. Sounds simple, but I’ve been stuck on this for days.

The time data array is retrieved from the controller via ‘dataProvider’=>‘enddate’ and is in the format YYYY-MM-DD hh:mm:ss. bytes is an integer.

I have this working if I use the xAxis categories for the times.

ie.


$this->Widget('ext.ActiveHighcharts.HighchartsWidget', array(

    'dataProvider'=>$dataProvider,

    'template'=>'{items}',

    'options'=> array(

        'xAxis'=>array(

            'title' => array('text' => 'Time',),

         'categories' => 'enddate',

           ),

        'series'=>array(

            array(

                  'type'=>'spline',

                  'name'=>'Download',      //title of data

                   'dataResource'=>'bytesout', //data resource according to database column

                 ),

         ),

     ),

);



But my times are not regular intervals, so I want it use a timedate ‘type’ and pass the times and bytes as x,y data in the ‘series’ data.

i.e




        'xAxis'=>array(

           'type'=>'datetime',

           'title' => array('text' => 'Time',),

         ),

        'series'=>array(

           array(

                  'type'=>'spline',

                'name'=>'Download',      //title of data

                'dataResource'=>array('enddate','bytesout'), //data resource according to datebase column

                 ),

         ),



There seems to be an issue with how I am passing the x,y as the chart is blank.

After looking at api.highcharts.com/highcharts#series.data.y I have also tried the following but still can’t get it working.




'dataResource'=>array('x'=>'enddate','y'=>'bytesout'),



[size="2"]Here is one (of many possible?) solutions to the problem above.

First of all, mysql datetimes are no good for highchart datetime graphs. They need to be JS times, or Unix Timestamps x 1000. i.e. milliseconds since 1 Jan 1970. So using PHPs strtotime() function fixed this.

Secondly, I found my y-axis bytes were not integers, they were strings. So using PHP intval() fixed this.

Thirdly, the x,y data series can’t just be an array with two variables (time and bytes respectively) like this. [/size]




Array ( [0] => [1390931883000, 30499975]

	[1] => [1392249315000, 4567432])



It needs to be[size="2"] a nested array. [/size]The print_r() output of the array needs to look like this

[size="2"]




Array ( [0] => Array ( [0] => 1400368522000 [1] => 59927722 ) 

	[1] => Array ( [0] => 1400367622000 [1] => 59660418 )

	[2] => Array ( [0] => 1400366722000 [1] => 59540379 ) )

[/size]

print_r() was my friend when nutting out what was required.

So with all this in mind, I ditched activehighcharts extension used highcharts instead as I couldn’t use the raw dataprovider output, and put the necessary code in my Controller to build the x,y data array.

So, the View becomes fairly simple




$this->Widget('ext.highcharts.HighchartsWidget', array(

        'options'=>array([/size]

              'title' => array('text' => 'Usage Summary'),

              'xAxis'=>array(

                        'type'=>'datetime',

                        'title' => array('text' => 'Time',),

                        ),[/size]

]              'yAxis' => array(

                        'title' => array('text' => 'bytes')

                        ),

              'series' => array(

         				array('name' => 'Download',

           					'data' => $downloaddata

                ) //end series

        ) // end options

));

Controller Snippet




public function actionIndex()

{

$dataProvider=new CActiveDataProvider('Rawusage');


// Prepare another array for the chart

// use eager loading to get the records we are after


foreach ($dataProvider->getData() as $record) { // get each record one by one

   $datetime  = $record->enddate;

   $datetime  = strtotime($record->enddate); // change Mysql date to Unix Timestamp

   $datetime *= 1000; // convert from Unix timestamp to JavaScript time

  $downloaddata[] = array($datetime, intval($record->bytesout));

}

 $this->render('index',array( // pass $downloaddata to view.

 	'dataProvider'=>$dataProvider, 'downloaddata'=>$downloaddata

 ));

}