Added google chart
This commit is contained in:
155
modules/gchart/classes/GoogleChart/ComboChart.php
Normal file
155
modules/gchart/classes/GoogleChart/ComboChart.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides access to Google's Chart API
|
||||
*
|
||||
* @package lnApp
|
||||
* @subpackage GoogleChart
|
||||
* @category Helper
|
||||
* @author Deon George
|
||||
* @copyright (c) 2010 Deon George
|
||||
* @license http://dev.leenooks.net/license.html
|
||||
*/
|
||||
class GoogleChart_ComboChart extends GoogleChart {
|
||||
// Should the Y column range be a log() function
|
||||
protected $_logy = FALSE;
|
||||
// Should the bar values be stacked
|
||||
protected $_stacked = FALSE;
|
||||
// Default line type to use
|
||||
protected $_type = 'bars';
|
||||
|
||||
public function logy($value) {
|
||||
$this->_logy = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function stacked($value) {
|
||||
$this->_stacked = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of the chart
|
||||
* @param $type Chart type as per $this->cht
|
||||
*/
|
||||
public function ltitle($side,$title) {
|
||||
if (! in_array($side,array('yl','yr','x')))
|
||||
throw new Kohana_Exception('Unknown side :side',array(':side'=>$side));
|
||||
|
||||
$this->_ltitle[$side] = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function json() {
|
||||
$return = array();
|
||||
|
||||
$return['cols'][] = array(
|
||||
'id'=>'date',
|
||||
'label'=>'date',
|
||||
'type'=>'string',
|
||||
);
|
||||
|
||||
// Columns
|
||||
foreach (array_keys($this->_axis) as $l) {
|
||||
$return['cols'][] = array(
|
||||
'id'=>$l,
|
||||
'label'=>$l,
|
||||
'type'=>'number',
|
||||
);
|
||||
}
|
||||
|
||||
// Values
|
||||
foreach ($this as $k => $v) {
|
||||
$data = array();
|
||||
|
||||
array_push($data,array('v'=>$k));
|
||||
|
||||
foreach ($this->_axis as $l => $axis)
|
||||
array_push($data,array('v'=>$v[$l]));
|
||||
|
||||
$return['rows'][] = array('c'=>$data);
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'bar' => array('groupWidth'=>'75%'),
|
||||
'vAxis' => array('logScale'=>$this->_logy ? 1:0),
|
||||
'title' => $this->_title,
|
||||
'isStacked' => $this->_stacked ? 1:0,
|
||||
'seriesType' => $this->_type,
|
||||
'series' => $this->series(),
|
||||
);
|
||||
|
||||
return json_encode(array('data'=>$return,'options'=>$options));
|
||||
}
|
||||
|
||||
public function render() {
|
||||
Script::add(array(
|
||||
'type'=>'src',
|
||||
'data'=>'https://www.google.com/jsapi',
|
||||
));
|
||||
|
||||
Script::add(array(
|
||||
'type'=>'stdin',
|
||||
'data'=>'google.load("visualization", "1", {packages: ["corechart"]});',
|
||||
));
|
||||
|
||||
Script::add(array(
|
||||
'type'=>'stdin',
|
||||
'data'=>"
|
||||
function drawChart".$this->_divname."() {
|
||||
var jsonData = $.ajax({
|
||||
url: '".$this->_dataurl."',
|
||||
dataType:'json',
|
||||
async: false,
|
||||
}).responseText;
|
||||
|
||||
var x = JSON.parse(jsonData);
|
||||
for(var key in x) {
|
||||
if (key == 'data')
|
||||
data = x[key];
|
||||
else if (key == 'options')
|
||||
options = x[key];
|
||||
else
|
||||
alert('UNKNOWN Key: '+key);
|
||||
}
|
||||
|
||||
// Create our data table out of JSON data loaded from server.
|
||||
var data = new google.visualization.DataTable(data);
|
||||
|
||||
// Instantiate and draw our chart, passing in some options.
|
||||
var chart = new google.visualization.ComboChart(document.getElementById('".$this->_divname."'));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
",
|
||||
));
|
||||
|
||||
Script::add(array(
|
||||
'type'=>'stdin',
|
||||
'data'=>'google.setOnLoadCallback(drawChart'.$this->_divname.');',
|
||||
));
|
||||
|
||||
return sprintf('<div id="%s" style="width: %spx; height: %spx;"></div>',$this->_divname,$this->_width,$this->_height);
|
||||
}
|
||||
|
||||
private function series() {
|
||||
$return = array();
|
||||
$c = $this->seriescolors();
|
||||
|
||||
$i = 0;
|
||||
foreach ($this->_axis as $l => $axis) {
|
||||
// @todo This shouldnt be hard coded
|
||||
if ($axis == 'yl')
|
||||
array_push($return,array('type'=>'bar','color'=>$c[$i],'targetAxisIndex'=>0));
|
||||
else
|
||||
array_push($return,array('type'=>'line','color'=>$c[$i],'targetAxisIndex'=>1));
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
?>
|
221
modules/gchart/classes/GoogleChart/Legacy.php
Normal file
221
modules/gchart/classes/GoogleChart/Legacy.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides access to Google's Chart Legacy API
|
||||
*
|
||||
* @package lnApp
|
||||
* @subpackage GoogleChart
|
||||
* @category Helper
|
||||
* @author Deon George
|
||||
* @copyright (c) 2010 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;
|
||||
}
|
||||
}
|
||||
?>
|
Reference in New Issue
Block a user