This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
khosb/modules/gchart/classes/GoogleChart/Legacy.php
2013-03-20 23:04:51 +11:00

221 lines
5.5 KiB
PHP

<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides access to Google's Chart Legacy API
*
* @package GoogleChart
* @category Helper
* @author Deon George
* @copyright (c) 2009-2013 Deon George
* @license http://dev.leenooks.net/license.html
*/
class GoogleChart_Legacy extends GoogleChart {
// Chart URL
private $_url = 'http://chart.apis.google.com/chart';
// The type of chart we'll plot
private $_type = 'bvs';
// Data encoding type to use
private $_encodetype = 's';
// Chart Types
private $cht = array(
// Line
// 'line' => 'lc',
// 'sparkline' => 'ls',
// 'line_xy' => 'lxy',
// Bar
// 'horizontal_bar' => 'bhs',
'vertical_bar' => 'bvs',
// 'horizontal_bar_grp' => 'bhg',
// 'vertical_bar_grp' => 'bvg',
// Pie
// 'pie' => 'p',
// 'pie_3d' => 'p3',
// 'pie_concentric' => 'pc',
// Venn
// 'venn' => 'v',
// Scatter
// 'scatter' => 's',
// Radar
// 'radar' => 'r',
// 'radar_fill' => 'rs',
// Maps
// 'map' => 't',
// Google-o-meter
// 'google_o_meter' => 'gom',
// QR
// 'qr' => 'qr',
);
/**
* Set the type of the chart
* @param $type Chart type as per $this->cht
*/
public function type($type) {
if (empty($this->cht[$type]))
throw new Kohana_Exception('Unknown chart type :type for :class',array(':type'=>$type,':class'=>get_class($this)));
$this->_type = $this->cht[$type];
return $this;
}
/**
* Count how many metrics are being graphed per side
* @param $side Side YL (left) OR YR (right)
*/
private function axiscount($side) {
$i = 0;
foreach ($this->_axis as $l => $axis)
if ($axis == $side)
$i++;
return $i;
}
/**
* Calculate our maximum for each side of the chart
*/
private function maxes() {
$return = array();
foreach ($this->_axis as $l => $axis) {
if (! isset($return[$axis]))
$return[$axis] = 0;
$return[$axis] += $this->_max[$l]*1.1; // @todo This scaleup should be configurable
}
return $return;
}
/** CHART FIELDS **/
private function chd() {
$return = array();
$maxes = $this->maxes();
// Perform our encoding
foreach ($this->_axis as $l => $axis)
array_push($return,$this->encode($this->_data[$l],$maxes[$axis]));
$prefix = (count($maxes) > 1) ? sprintf('%s:',$this->axiscount('yl')) : ':';
// If encoding is text, we need to separate the series with a |
return ($this->_encodetype == 't') ? $prefix.implode('|',$return) : $prefix.implode(',',$return);
}
private function chm() {
$return = array();
$sc = $this->seriescolors();
$i = 0;
foreach ($this->_axis as $l => $axis) {
if ($axis == 'yr')
array_push($return,sprintf('%s,%s,%s,%s,%s,%s','D',$sc[$i],$i,0,2,2));// @todo 'D,0,2,2' May need to be configurable
$i++;
}
return count($return) ? implode('|',$return) : '';
}
private function chxl() {
$return = array();
// @todo This should be performed better - it may be a wrong assumption that all keys in the series have data.
foreach ($this->_data as $series => $data)
// @todo Why the 0:?
return '0:|'.implode('|',array_keys($data));
}
private function chxr() {
$return = array();
$i = 1;
foreach ($this->maxes() as $key => $value)
array_push($return,sprintf('%s,0,%s,0',$i++,$value));
return implode('|',$return);
}
public function json() {}
/**
* Return URL that renders the chart
*/
public function render() {
return sprintf('<img src="%s?%s" alt="%s">',$this->_url,http_build_query($this->build()),_('Google Chart'));
}
/**
* Build the chart
*/
private function build() {
if ($this->_data ) {
return array(
'chf'=>'bg,s,FFFFFF00',
'cht'=>$this->_type,
'chs'=>sprintf('%sx%s',$this->_width,$this->_height),
'chtt'=>$this->_title,
'chbh'=>'a', // @todo This might need to be calculated, valid options (a,r);
'chg'=>'7.7,12.5,1,5', // @todo This should be calculated
'chco'=>implode(',',$this->seriescolors()),
'chdl'=>implode('|',array_keys($this->_axis)),
'chd'=>$this->_encodetype.$this->chd(),
'chm'=>$this->chm(),
'chxt'=>'x,y,r', // @todo configurable?
'chxl'=>$this->chxl(),
'chxr'=>$this->chxr(),
);
} else
return array();
}
/**
* Encode the series data
* @param $data String of data to encode
* @param $max The maximum to scale to
*/
private function encode($data,$max=NULL) {
$table = array();
$table['simple'] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$table['extend'] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.';
$size = array();
$size['simple'] = strlen($table['simple']);
$size['extend'] = strlen($table['extend']);
if (is_null($max) OR $max == 0)
$max = max($data) > 0 ? max($data) : 1;
$encode = '';
switch ($this->_encodetype) {
case 't' :
return join(',',$data);
case 's' :
foreach ($data as $v)
$encode .= ($v > -1) ? substr($table['simple'],($size['simple']-1)*($v/$max),1) : '_';
break;
case 'e' :
foreach ($data as $v) {
# Convert to a 0-4095 data range
$y = 4095*$v/$max;
$first = substr($table['extend'],floor($y/$size['extend']),1);
$second = substr($table['extend'],$y%$size['extend'],1);
$encode .= "$first$second";
}
break;
}
return $encode;
}
}
?>