'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() { $result = array(); foreach ($this->_axis as $l => $axis) { if (! isset($result[$axis])) $result[$axis] = 0; $result[$axis] += $this->_max[$l]*1.1; // @todo This scaleup should be configurable } return $result; } /** CHART FIELDS **/ private function chd() { $result = array(); $maxes = $this->maxes(); // Perform our encoding foreach ($this->_axis as $l => $axis) array_push($result,$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('|',$result) : $prefix.implode(',',$result); } private function chm() { $result = array(); $sc = $this->seriescolors(); $i = 0; foreach ($this->_axis as $l => $axis) { if ($axis == 'yr') array_push($result,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($result) ? implode('|',$result) : ''; } private function chxl() { $result = 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() { $result = array(); $i = 1; foreach ($this->maxes() as $key => $value) array_push($result,sprintf('%s,0,%s,0',$i++,$value)); return implode('|',$result); } public function json() {} /** * Return URL that renders the chart */ public function render() { return sprintf('%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; } } ?>