SSL, Google Chart updates, lnAPP improvements
This commit is contained in:
176
modules/gchart/classes/GoogleChart.php
Normal file
176
modules/gchart/classes/GoogleChart.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?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
|
||||
*/
|
||||
abstract class GoogleChart implements Iterator,Countable {
|
||||
// Hold the data for our chart
|
||||
protected $_data = array();
|
||||
protected $_axis = array();
|
||||
private $_plotdata = array();
|
||||
protected $_max = array();
|
||||
// Chart title
|
||||
protected $_title = '';
|
||||
// Default chart size.
|
||||
protected $_size = '700x200';
|
||||
|
||||
// Colors to use for series
|
||||
private $series_colors = array('AAACCC','E0E0E0','CCC888','EEEBBB','666CCC','888888');
|
||||
|
||||
// Implementation Methods
|
||||
public function count() {
|
||||
return count($this->_plotdata);
|
||||
}
|
||||
public function current() {
|
||||
return current($this->_plotdata);
|
||||
}
|
||||
public function key() {
|
||||
return key($this->_plotdata);
|
||||
}
|
||||
public function next() {
|
||||
return next($this->_plotdata);
|
||||
}
|
||||
public function rewind() {
|
||||
reset($this->_plotdata);
|
||||
}
|
||||
public function valid() {
|
||||
return key($this->_plotdata) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
public function __call($name,$args) {
|
||||
switch ($name) {
|
||||
case 'title': $this->_title = array_shift($args);
|
||||
break;
|
||||
default:
|
||||
throw new Kohana_Exception('Unknown method :name',array(':name'=>$name));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the URL that generates the graph
|
||||
*/
|
||||
final public function __toString() {
|
||||
try {
|
||||
return (string)$this->render();
|
||||
} catch (Exception $e) {
|
||||
echo Debug::vars($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick the driver that will render the graph
|
||||
* @param $class The child class to invoke
|
||||
*/
|
||||
final public static function factory($class) {
|
||||
$c = sprintf('%s_%s',get_called_class(),$class);
|
||||
|
||||
if (! class_exists($c))
|
||||
throw new Kohana_Exception('Unknown Google Chart Type :class',array(':class'=>$class));
|
||||
else
|
||||
return new $c();
|
||||
}
|
||||
|
||||
// Our child class should define how to render as a string
|
||||
abstract public function render();
|
||||
|
||||
/**
|
||||
* Record one series of data
|
||||
* @param $axis Axis used and legend title, eg: (yr->"Right Y",yl->"Left Y")
|
||||
* @param $data Data for Axis in the format ("x label"=>value);
|
||||
*
|
||||
* Example:
|
||||
* $this->data('yl'=>'Base Down Peak',array('11-12'=>1,'11-11'=>2));
|
||||
*/
|
||||
public function data(array $axis,array $data) {
|
||||
// Some sanity checking
|
||||
if (count($axis) != 1)
|
||||
throw new Kohana_Exception('We can only take 1 series at time.');
|
||||
|
||||
// This should only iterate once
|
||||
foreach ($axis as $key => $l) {
|
||||
if (! in_array($key,array('yr','yl')))
|
||||
throw new Kohaan_Exception('Unknown AXIS :axis',array(':axis'=>$key));
|
||||
|
||||
$this->_axis[$l] = $key;
|
||||
$this->_data[$l] = $data[$l];
|
||||
|
||||
// Upate our plot data
|
||||
foreach ($data[$l] as $k=>$v)
|
||||
$this->_plotdata[$k][$l] = $v;
|
||||
|
||||
ksort($this->_plotdata);
|
||||
|
||||
$this->_max[$l] = max($data[$l]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the colors that will be used for this series
|
||||
*/
|
||||
protected function seriescolors() {
|
||||
return array_slice($this->series_colors,0,count($this->_axis));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the chart data in a table format
|
||||
*/
|
||||
public function table($vertical=TRUE,$class=array()) {
|
||||
if (! $this->_data)
|
||||
return sprintf('<table><tr><td>%s</td></tr></table>',_('No Data'));
|
||||
|
||||
$output = sprintf('<table %s>',
|
||||
isset($class['table']) ? $class['table'] : 'class="google-data-table"');
|
||||
|
||||
if ($vertical) {
|
||||
$output .= '<tr>';
|
||||
$output .= '<td> </td>';
|
||||
foreach ($this->_axis as $l => $axis)
|
||||
$output .= sprintf('<th style="text-align: right;">%s</th>',$l);
|
||||
|
||||
$output .= '</tr>';
|
||||
|
||||
foreach ($this as $k => $details) {
|
||||
$output .= '<tr>';
|
||||
$output .= sprintf('<th style="text-align: right;">%s</th>',$k);
|
||||
foreach ($this->_axis as $l => $axis)
|
||||
$output .= sprintf('<td style="text-align: right;">%s</td>',$details[$l]);
|
||||
$output .= '</tr>';
|
||||
}
|
||||
|
||||
// Horizontal table
|
||||
} else {
|
||||
$output .= '<tr>';
|
||||
$output .= '<td> </td>';
|
||||
foreach ($this as $k => $details)
|
||||
$output .= sprintf('<th style="text-align: right;">%s</th>',$k);
|
||||
$output .= '</tr>';
|
||||
|
||||
foreach ($this->_axis as $l => $axis) {
|
||||
$output .= '<tr>';
|
||||
|
||||
$output .= sprintf('<th style="text-align: right;">%s</th>',$l);
|
||||
|
||||
foreach ($this as $k => $v)
|
||||
$output .= sprintf('<td style="text-align: right;">%s</td>',$v[$l]);
|
||||
|
||||
$output .= '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
$output .= '</table>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
?>
|
219
modules/gchart/classes/GoogleChart/Legacy.php
Normal file
219
modules/gchart/classes/GoogleChart/Legacy.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'=>$this->_size,
|
||||
'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;
|
||||
}
|
||||
}
|
||||
?>
|
@@ -1,423 +0,0 @@
|
||||
<?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 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class GoogleChart implements Iterator,Countable {
|
||||
// Chart URL
|
||||
private $url = 'http://chart.apis.google.com/chart';
|
||||
// Hold our plot data
|
||||
private $plotdata = array();
|
||||
private $chartdata = array();
|
||||
// Number of Series to plot
|
||||
private $numseries = 0;
|
||||
// The type of chart we'll plot
|
||||
private $chart_type = '';
|
||||
// Default chart tytle.
|
||||
private $chart_title = '';
|
||||
// Default chart size.
|
||||
private $chart_size = '700x200';
|
||||
// Colors to use for series
|
||||
private $series_colors = array('AAACCC','E0E0E0','CCC888','EEEBBB','666CCC','888888');
|
||||
// Data encoding type to use
|
||||
private $data_encode = 's';
|
||||
private $div_mode = FALSE;
|
||||
|
||||
// Implementation Methods
|
||||
public function rewind() {
|
||||
reset($this->plotdata);
|
||||
}
|
||||
public function current() {
|
||||
return current($this->plotdata);
|
||||
}
|
||||
public function key() {
|
||||
return key($this->plotdata);
|
||||
}
|
||||
public function next() {
|
||||
return next($this->plotdata);
|
||||
}
|
||||
public function valid() {
|
||||
return key($this->plotdata) ? TRUE : FALSE;
|
||||
}
|
||||
public function count() {
|
||||
return count($this->plotdata);
|
||||
}
|
||||
|
||||
// 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',
|
||||
);
|
||||
|
||||
public function __construct($type) {
|
||||
if (empty($this->cht[$type]))
|
||||
throw new Kohana_Exception('Unknown chart type :type for :class',array(':type'=>$type,':class'=>get_class($this)));
|
||||
|
||||
$this->chart_type = $this->cht[$type];
|
||||
}
|
||||
|
||||
public function __set($key,$value) {
|
||||
switch ($key) {
|
||||
case 'div':
|
||||
$this->div_mode = $value;
|
||||
break;
|
||||
|
||||
case 'encode':
|
||||
// Encoding options are t=none,s=simple,e=extend
|
||||
if (! in_array($value,array('t','s','e')))
|
||||
throw new Kohana_Exception('Unknown encoding type :type',array(':type'=>$value));
|
||||
|
||||
$this->data_encode = $value;
|
||||
break;
|
||||
|
||||
case 'title':
|
||||
$this->chart_title = $value;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Kohana_Exception('Unknown variable :key (:value) for :class',array(':key'=>$key,':value'=>$value,':class'=>get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
try {
|
||||
return $this->render();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo Debug::vars($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of this class
|
||||
*
|
||||
* @return GoogleChart
|
||||
*/
|
||||
public static function factory($type) {
|
||||
return new GoogleChart($type);
|
||||
}
|
||||
|
||||
public function series($data) {
|
||||
// Quick Sanity check that we have the right indexes
|
||||
foreach (array('data','axis') as $k)
|
||||
if (! isset($data[$k]))
|
||||
throw new Kohana_Exception('Missing key :key',array(':key'=>$k));
|
||||
|
||||
// Quick check that we have the right types
|
||||
if (! in_array($data['axis'],array('x','r')))
|
||||
throw new Kohana_Exception('Unknown data type :type',array(':type'=>$data['axis']));
|
||||
|
||||
if (is_array($data['data'])) {
|
||||
foreach ($data['data'] as $title => $values) {
|
||||
$this->numseries++;
|
||||
|
||||
$this->chartdata['legend'][$this->numseries] = $title;
|
||||
$this->chartdata['axis'][$data['axis']][] = $this->numseries;
|
||||
|
||||
if (is_array($values))
|
||||
foreach ($values as $k => $v)
|
||||
$this->plotdata[$k][$data['axis']][$this->numseries] = $v;
|
||||
else
|
||||
throw new Kohana_Exception('Series data needs to be an array');
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new Kohana_Exception('Series data needs to be an array');
|
||||
}
|
||||
}
|
||||
|
||||
private function seriescolors() {
|
||||
$return = array();
|
||||
|
||||
$i = 0;
|
||||
for ($j=0;$j<$this->numseries;$j++) {
|
||||
array_push($return,$this->series_colors[$i++]);
|
||||
|
||||
// Reset $i if we exceed our available colors
|
||||
if ($i > count($this->series_colors))
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function series_colors() {
|
||||
return implode(',',$this->seriescolors());
|
||||
}
|
||||
|
||||
public function series_chm() {
|
||||
if (! isset($this->chartdata['axis']['r']))
|
||||
return '';
|
||||
|
||||
$return = array();
|
||||
$c = $this->seriescolors();
|
||||
foreach ($this->chartdata['axis']['r'] as $v)
|
||||
array_push($return,sprintf('%s,%s,%s,%s,%s,%s','D',$c[$v-1],$v-1,0,2,2));// @todo 'D,0,2,2' May need to be configurable
|
||||
|
||||
return implode('|',$return);
|
||||
}
|
||||
|
||||
public function series_x_labels() {
|
||||
// @todo Why the 0:?
|
||||
return '0:|'.implode('|',array_keys($this->plotdata));
|
||||
}
|
||||
|
||||
public function series_scaling() {
|
||||
$return = array();
|
||||
|
||||
foreach ($this->chartdata['max'] as $k => $v)
|
||||
array_push($return,sprintf('%s,%s',empty($this->chartdata['min']) ? 0 : $this->chartdata['min'],$v));
|
||||
|
||||
return implode(',',$return);
|
||||
}
|
||||
|
||||
public function series_scale() {
|
||||
$return = array();
|
||||
|
||||
$i = 1;
|
||||
// @todo need to add min values
|
||||
foreach ($this->chartdata['max'] as $k => $v)
|
||||
array_push($return,sprintf('%s,0,%s,0',$i++,$v));
|
||||
|
||||
return implode('|',$return);
|
||||
}
|
||||
|
||||
public function series_legend() {
|
||||
return implode('|',$this->chartdata['legend']);
|
||||
}
|
||||
|
||||
public function series_data() {
|
||||
$return = $sreturn = $invs = array();
|
||||
|
||||
$sd = $max = array();
|
||||
foreach ($this->plotdata as $label => $seriesdata)
|
||||
foreach ($seriesdata as $type => $data) {
|
||||
foreach ($data as $key => $value) {
|
||||
$sd[$key][$label] = $value;
|
||||
$max[$key] = $this->chartdata['max'][$type];
|
||||
$invs[$type][$key] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($sd as $k => $v)
|
||||
array_push($sreturn,$this->encode($v,$max[$k]));
|
||||
|
||||
// @todo This might need some more work, when used with different graph types.
|
||||
if (count($invs) > 1)
|
||||
$prefix = sprintf('%s:',count($invs['x']));
|
||||
else
|
||||
$prefix = ':';
|
||||
|
||||
// If encoding is text, we need to separate the series with a |
|
||||
if ($this->data_encode == 't')
|
||||
return $prefix.implode('|',$sreturn);
|
||||
else
|
||||
return $prefix.implode(',',$sreturn);
|
||||
}
|
||||
|
||||
private function render() {
|
||||
$output = '';
|
||||
|
||||
// Testing
|
||||
if ($this->div_mode) {
|
||||
$output .= '<div id="GoogleChart">GoogleChart</div>';
|
||||
$output .= '<div id="showgc" style="display: inline;">';
|
||||
}
|
||||
|
||||
// Render
|
||||
$output .= sprintf('<img src="%s?%s" alt="%s">',$this->url,http_build_query($this->build()),_('Traffic Summary'));
|
||||
// $output .= Debug::vars($this->build());
|
||||
// $output .= Debug::vars($this->chartdata);
|
||||
// $output .= Debug::vars($this->plotdata);
|
||||
|
||||
// Toggle the display of the chart.
|
||||
// @todo This JS should be placed elsewhere for HTML validation
|
||||
if ($this->div_mode) {
|
||||
$output .= '</div>';
|
||||
$output .= '<script type="text/javascript">$("#GoogleChart").click(function() {$(\'#showgc\').toggle();});</script>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function html_table($vertical=TRUE,$class=array()) {
|
||||
if (! count($this))
|
||||
return sprintf('<table><tr><td>%s</td></tr></table>',_('No Data'));
|
||||
|
||||
$output = sprintf('<table %s>',
|
||||
isset($class['table']) ? $class['table'] : 'class="google-data-table"');
|
||||
|
||||
if ($vertical) {
|
||||
$output .= '<tr>';
|
||||
$output .= '<td> </td>';
|
||||
foreach ($this->chartdata['axis'] as $axis => $adetails)
|
||||
foreach ($adetails as $k)
|
||||
$output .= sprintf('<th style="text-align: right;">%s</th>',$this->chartdata['legend'][$k]);
|
||||
$output .= '</tr>';
|
||||
|
||||
foreach ($this as $k => $v) {
|
||||
$output .= '<tr>';
|
||||
$output .= sprintf('<th style="text-align: right;">%s</th>',$k);
|
||||
foreach ($this->chartdata['axis'] as $axis => $adetails)
|
||||
foreach ($adetails as $k)
|
||||
$output .= sprintf('<td style="text-align: right;">%s</td>',$v[$axis][$k]);
|
||||
$output .= '</tr>';
|
||||
}
|
||||
|
||||
// Horizontal table
|
||||
} else {
|
||||
$output .= '<tr>';
|
||||
$output .= '<td> </td>';
|
||||
foreach ($this as $k => $v)
|
||||
$output .= sprintf('<th style="text-align: right;">%s</th>',$k);
|
||||
$output .= '</tr>';
|
||||
|
||||
foreach ($this->chartdata['axis'] as $axis => $adetails)
|
||||
foreach ($adetails as $id) {
|
||||
$output .= '<tr>';
|
||||
|
||||
$output .= sprintf('<th style="text-align: right;">%s</th>',$this->chartdata['legend'][$id]);
|
||||
|
||||
foreach ($this as $k => $v)
|
||||
$output .= sprintf('<td style="text-align: right;">%s</td>',$v[$axis][$id]);
|
||||
|
||||
$output .= '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
$output .= '</table>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some pre-render processing
|
||||
*/
|
||||
private function process() {
|
||||
$max = array();
|
||||
|
||||
// Work out our maximum number for each series.
|
||||
foreach ($this->plotdata as $label => $seriesdata) {
|
||||
|
||||
foreach ($seriesdata as $type => $data) {
|
||||
$c = 0;
|
||||
foreach ($data as $value)
|
||||
$c += $value;
|
||||
|
||||
// Scale up our max, so we get some extra space at the top of our chart.
|
||||
// @todo This should be configurable.
|
||||
$c *= 1.1;
|
||||
|
||||
if (! isset($this->chartdata['max'][$type]))
|
||||
$this->chartdata['max'][$type] = $c;
|
||||
else
|
||||
$this->chartdata['max'][$type] = ($c > $this->chartdata['max'][$type]) ? $c : $this->chartdata['max'][$type];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the chart
|
||||
*/
|
||||
private function build() {
|
||||
if ($this->plotdata) {
|
||||
$this->process();
|
||||
|
||||
return array(
|
||||
'chf'=>'bg,s,FFFFFF00',
|
||||
'cht'=>$this->chart_type,
|
||||
'chs'=>$this->chart_size,
|
||||
'chtt'=>$this->chart_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'=>$this->series_colors(),
|
||||
'chdl'=>$this->series_legend(),
|
||||
'chd'=>$this->data_encode.$this->series_data(),
|
||||
// 'chds'=>$this->series_scaling(),
|
||||
'chm'=>$this->series_chm(),
|
||||
'chxt'=>'x,y,r', // @todo configurable?
|
||||
'chxl'=>$this->series_x_labels(),
|
||||
'chxr'=>$this->series_scale(),
|
||||
);
|
||||
|
||||
} else
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the series data
|
||||
*/
|
||||
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->data_encode) {
|
||||
case 't' :
|
||||
return join(',',$data);
|
||||
|
||||
case 's' :
|
||||
foreach ($data as $v)
|
||||
if ($v > -1)
|
||||
$encode .= substr($table['simple'],($size['simple']-1)*($v/$max),1);
|
||||
else
|
||||
$encode .= '_';
|
||||
|
||||
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