Highcharts Library for CodeIgniter

Hi everyone, in this post I’ll talk about a Codeigniter library that I’ve done after few hours using highchart. Highchart is one of the best javascript library i’ve ever used to render beautiful charts (which are compatible with iPhone and iPad). This library is awesome !
Here is a first draw of the library I’ve done, it’s not perfect but it’s working well for the simple graphs I had to do. Let’s see this HighChart library.
Basically HighChart is using a json array, to render the graph. All the configuration and the data are located into this array of options. What I’ve done in this library it’s just fill this array of option before to build the javascript code to render the graph. Let’s have a look to the code.
class Highcharts_lib{
private $a_options;
private $s_rendering;
private $i_serie_index;
Here is the basic class named “Highcharts_lib”. As you can see there is 3 private variables. The first one “$a_options” is as we said before all the configuration of the graphs plus de data of the series. “$s_rendering” will store the javascript code to insert into your view to render the graph. And finally “$i_serie_index” is an index which allow us to store severals series into the option array. Let’s continue…
function __construct(){
$this->a_options=array();
# Set Default Values
$this->set_container_id('highchart_id');
$this->set_graph_type('spline');
$this->display_credit(FALSE);
$this->i_serie_index = 0;
$this->a_options['series'] = array();
}
Into the constructor I’m just initialising some variables and some default configuration for the graphs.
For exemple, set_container_id() is a method to set the ID of the container (div) of the graph:
function set_container_id($s_id=''){
if(trim($s_id)!= ''){
$this->a_options['chart']['renderTo'] = $s_id;
}
return $this;
}
As you can see we just set a value into the array of options and return the object. This is very important, “return $this” will allow us to do what we call “Methods chaining” which is very useful when you have to set some few options. I won’t explain the others methods as they are very similar to the one I’ve explained. We will now focus on the series.
To manage the series of the graphs I’m using 4 methods, here they are:
/* Series Options */
function add_serie($s_serie_name='', $a_value=array(), $s_type=''){
$s_serie_name = trim($s_serie_name);
if($s_serie_name != '' && is_array($a_value)){
$f=false;
foreach($this->a_options['series'] as $index => $serie){
if(strtolower($serie['name']) == strtolower($s_serie_name)){
$f=$index;
break;
}
}
if( $f!==FALSE ){
foreach($a_value as $value){
$value = (is_numeric($value)) ? (float)$value : $value;
$this->a_options['series'][$f]['data'][] = $value;
}
}else{
$this->a_options['series'][$this->i_serie_index]['name'] = $s_serie_name;
foreach($a_value as $value){
$value = (is_numeric($value)) ? (float)$value : $value;
$this->a_options['series'][$this->i_serie_index]['data'][] = $value;
}
$this->set_serie_option($s_serie_name, 'type', $s_type);
$this->i_serie_index++;
}
}
return $this;
}
function set_serie($s_serie_name='', $a_value=array()){
$s_serie_name = trim($s_serie_name);
if($s_serie_name != '' && is_array($a_value)){
$f=false;
foreach($this->a_options['series'] as $index => $serie){
if(strtolower($serie['name']) == strtolower($s_serie_name)){
$f=$index;
break;
}
}
if( $f !== FALSE ){
# Reset the serie
$this->a_options['series']['data'][$f] = array();
foreach($a_value as $value){
$value = (is_numeric($value)) ? (float)$value : $value;
$this->a_options['series'][$f]['data'][] = $value;
}
}else{
$this->add_serie($s_serie_name, $a_value);
}
}
return $this;
}
function push_serie_data($s_serie_name = '', $s_value=''){
if($s_serie_name != '' && $s_value !='' ){
$f=false;
foreach($this->a_options['series'] as $index => $serie){
if(strtolower($serie['name']) == strtolower($s_serie_name)){
$f=$index;
break;
}
}
if( $f !== FALSE ){
$s_value = (is_numeric($s_value)) ? (float)$s_value : $s_value;
$this->a_options['series'][$f]['data'][] = $s_value;
}else{
$this->add_serie($s_serie_name, array($s_value));
}
}
return $this;
}
function set_serie_options($s_serie_name='', $s_option_name='', $option_value=''){
if($s_serie_name != '' && $s_option_name !='' && $option_value!=''){
$f=false;
foreach($this->a_options['series'] as $index => $serie){
if(strtolower($serie['name']) == strtolower($s_serie_name)){
$f=$index;
break;
}
}
if( $f !== FALSE ){
$this->a_options['series'][$f][$s_option_name] = $option_value;
}
}
return $this;
}
This 4 methods need some more work but the result is here and it’s working. add_serie() as its name stand for is to add a serie. The first parameter is the name of the serie, this parameter is the most important. The name of the serie will we used into the legend by default, also we’ll use this name each time we need to push data into the serie. As you can see the second parameter allow us to set the data of the serie directly in here, but it’s not compulsory. And finally the last parameter is the type of the graph that we want to render for this serie.
The second method is to set the data of the series if you did not do it on the first time at the create of the serie. I have to tell that I’m not using this method but still it should work
The third method is to push data into the serie that you’ve created before. This method is the one I used the most and we’ll have a look into the exemple later on.
And finally the last option is to set options of the specific serie.
Let’s have a look to an exemple now
function view_graph(){
$this->library->load('Highcharts_lib');
# Set the graph using methods chaining
$this->Highcharts_lib
->set_graph_type('spline')
->toggle_legend(TRUE)
->display_shadow(TRUE)
->set_xlabels_otpions('rotation', -45)
->set_graph_title('')
->set_yAxis(array(), 'Clicks')
->add_serie('The first Serie', array())
->add_serie('This is the second Serie', array(),'areaspline');
# Set random data for the series
for($i=1 ; $i <=365 ; $i++){
$value = rand(100, 500);
$value_second_serie = rand(50, 70);
$this->Highcharts_lib->push_serie_data('The first Serie', $value);
$this->Highcharts_lib->push_serie_data('This is the second Serie', $value_second_serie);
// At the same time we set the axis label
$this->Highcharts_lib->push_xAxis_value($i);
}
# We can use debug to check the content of the options array
//$this->highcharts_lib->debug();
$s_graph = $this->Highcharts_lib->render(800,400);
$this-assign('graph_source', $s_graph);
$this->view('graphs.tpl');
}
As you can see methods chaining is very useful in here. I forgot to mention that you need to include the jQuery library into your template as HighChart is using this library to render the graphs. You can find bellow the whole library source, do not hesitate if you like to make some comments on it and thanks to read me
Here is the rendered graph:
And here the ull source of the library:
class Highcharts_lib{
private $a_options;
private $s_rendering;
private $i_serie_index;
function __construct(){
$this->a_options=array();
# Set Default Values
$this->set_container_id('highchart_id');
$this->set_graph_type('spline');
$this->display_credit(FALSE);
$this->i_serie_index = 0;
$this->a_options['series'] = array();
}
function set_chart_otpions($option_name, $option_value){
$option_name = trim($option_name);
if($option_name != ''){
if(is_array($option_value) && !empty($option_value)){
$this->a_options['chart'][$option_name] = json_encode($option_value);
}else{
$this->a_options['chart'][$option_name] = trim($option_value);
}
}
return $this;
}
function set_xlabels_otpions($option_name, $option_value){
$option_name = trim($option_name);
if($option_name != ''){
if(is_array($option_value) && !empty($option_value)){
$this->a_options['xAxis']['labels'][$option_name] = json_encode($option_value);
}else{
$this->a_options['xAxis']['labels'][$option_name] = trim($option_value);
}
}
return $this;
}
function set_ylabels_otpions($option_name, $option_value){
$option_name = trim($option_name);
if($option_name != ''){
if(is_array($option_value) && !empty($option_value)){
$this->a_options['yAxis']['labels'][$option_name] = json_encode($option_value);
}else{
$this->a_options['yAxis']['labels'][$option_name] = trim($option_value);
}
}
return $this;
}
/* Graph Options */
/**
* Set the title option
*
* @param String $s_title
* @param String $align
* @param Integer $x
* @param Integer $y
* @param CSSObject $a_css
* @return unknown
*/
function set_graph_title($s_title='', $align='center', $x=0, $y=20, $a_css=array()){
$this->a_options['title']['text'] = ($s_title=='') ? NULL : $s_title;
$this->a_options['title']['align'] = $align;
$this->a_options['title']['x'] = $x;
$this->a_options['title']['y'] = $y;
if(!empty($a_css)){
$this->a_options['title']['style'] = json_encode($a_css);
}
return $this;
}
function set_graph_margin($top=50, $right=50, $bottom=70, $left=80){
echo json_encode(array($top, $right, $bottom, $left));
$this->a_options['chart']['margin'] = json_encode(array($top, $right, $bottom, $left));
return $this;
}
function set_backgroundcolor($color='#000000'){
if(trim($color)!= ''){
$this->a_options['chart']['backgroundColor'] = $color;
}
return $this;
}
function display_shadow($bool=FALSE){
if(is_bool($bool)!= ''){
$this->a_options['chart']['shadow'] = $bool;
}
return $this;
}
function set_container_id($s_id=''){
if(trim($s_id)!= ''){
$this->a_options['chart']['renderTo'] = $s_id;
}
return $this;
}
function set_graph_type($s_type=''){
if(trim($s_type)!= ''){
$this->a_options['chart']['defaultSeriesType'] = $s_type;
}
return $this;
}
function toggle_legend($enabled=TRUE){
if(is_bool($enabled)){
$this->a_options['legend']['enabled'] = $enabled;
}
return $this;
}
function display_credit($enabled=TRUE){
if(is_bool($enabled)){
$this->a_options['credits']['enabled'] = $enabled;
}
return $this;
}
/* Axis Options */
function set_xAxis($a_value=array(), $title=FALSE){
if(is_array($a_value) && !empty($a_value)){
$this->a_options['xAxis']['categories'] = $a_value;
}
if($title !== FALSE && trim($title) != ''){
$this->a_options['xAxis']['title']['text'] = $title;
}
return $this;
}
function push_xAxis_value($value){
if(trim($value)!= ''){
$this->a_options['xAxis']['categories'][] = $value;
}
return $this;
}
function set_yAxis($a_value=array(), $title=FALSE){
if(is_array($a_value) && !empty($a_value)){
$this->a_options['yAxis']['categories'] = $a_value;
}
if($title !== FALSE && trim($title) != ''){
$this->a_options['yAxis']['title']['text'] = $title;
}
return $this;
}
function push_yAxis_value($value){
if(trim($value)!= ''){
$this->a_options['yAxis']['categories'][] = $value;
}
return $this;
}
/* Series Options */
function add_serie($s_serie_name='', $a_value=array(),$type=''){
$s_serie_name = trim($s_serie_name);
if($s_serie_name != '' && is_array($a_value)){
$f=false;
foreach($this->a_options['series'] as $index => $serie){
if(strtolower($serie['name']) == strtolower($s_serie_name)){
$f=$index;
break;
}
}
if( $f!==FALSE ){
if($type!=='')$this->a_options['series'][$f]['type'] = $type;
foreach($a_value as $value){
$value = (is_numeric($value)) ? (float)$value : $value;
$this->a_options['series'][$f]['data'][] = $value;
}
}else{
if($type!=='')$this->a_options['series'][$this->i_serie_index]['type'] = $type;
$this->a_options['series'][$this->i_serie_index]['name'] = $s_serie_name;
foreach($a_value as $value){
$value = (is_numeric($value)) ? (float)$value : $value;
$this->a_options['series'][$this->i_serie_index]['data'][] = $value;
}
$this->i_serie_index++;
}
}
return $this;
}
function set_serie($s_serie_name='', $a_value=array()){
$s_serie_name = trim($s_serie_name);
if($s_serie_name != '' && is_array($a_value)){
$f=false;
foreach($this->a_options['series'] as $index => $serie){
if(strtolower($serie['name']) == strtolower($s_serie_name)){
$f=$index;
break;
}
}
if( $f !== FALSE ){
# Reset the serie
$this->a_options['series']['data'][$f] = array();
foreach($a_value as $value){
$value = (is_numeric($value)) ? (float)$value : $value;
$this->a_options['series'][$f]['data'][] = $value;
}
}else{
$this->add_serie($s_serie_name, $a_value);
}
}
return $this;
}
function set_serie_option($s_serie_name='', $s_option='', $value=''){
# First we search the serie
$s_serie_name = trim($s_serie_name);
if($s_serie_name !== '' && $s_option!==''){
$f=false;
# We check that we have a serie with the name
foreach($this->a_options['series'] as $index => $serie){
if(strtolower($serie['name']) == strtolower($s_serie_name)){
$f=$index;
break;
}
}
# If Yes
if( $f !== FALSE ){
$this->a_options['series'][$f][$s_option] = $value;
}
}
return $this;
}
function push_serie_data($s_serie_name = '', $s_value=''){
if($s_serie_name !== '' && $s_value !=='' ){
$f=false;
foreach($this->a_options['series'] as $index => $serie){
//echo strtolower($serie['name'])." == ".strtolower($s_serie_name)."";
if(strtolower($serie['name']) == strtolower($s_serie_name)){
$f=$index;
break;
}
}
if( $f !== FALSE ){
$s_value = (is_numeric($s_value)) ? (float)$s_value : $s_value;
$this->a_options['series'][$f]['data'][] = $s_value;
}else{
$this->add_serie($s_serie_name, array($s_value));
}
}
return $this;
}
/* Render */
function render($width=FALSE,$height=FALSE,$div_id=FALSE){
$width = ($width !== FALSE && is_numeric($width)) ? $width.'px' : '100%';
$height = ($height !== FALSE && is_numeric($height)) ? $height.'px' : '400px';
$div_id = ($div_id !== FALSE && trim($div_id) != '') ? $div_id : $this->a_options['chart']['renderTo'];
$this->set_container_id($div_id);
$this->s_rendering = '<script src="/js/highcharts.js" type="text/javascript"></script>';
$this->s_rendering .= '<script>';
$this->s_rendering .= '$(document).ready(function(){';
$this->s_rendering .= 'var options = '.json_encode($this->a_options).';';
$this->s_rendering .= 'var chart = new Highcharts.Chart(options);';
$this->s_rendering .= '});';
$this->s_rendering .= '</script>';
$this->s_rendering .= '
';
return $this->s_rendering;
}
function debug(){
echo '<pre>';
print_r($this->a_options);
echo '</pre>';
}
}
The last method (debug) and class close have broken in the full source when you have inserted it into WP