Skip to content

Instantly share code, notes, and snippets.

@slywalker
Forked from ksz/google_chart.php
Created June 3, 2009 14:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save slywalker/123023 to your computer and use it in GitHub Desktop.
Save slywalker/123023 to your computer and use it in GitHub Desktop.
<?php
/**
* GoogleChart Helper
*
* The Google Chart API helper of CakePHP.
*
* @version 0.41
* @package ksz_cake_plugins
* @subpackage ksz_cake_plugins.tools
* @author ksz
* @link http://d.hatena.ne.jp/gapao/
* @copyright 2009 ksz
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
class GoogleChartHelper extends AppHelper
{
/**
* Google Chart API base Url
*
* @var string
*/
var $googleChartApi = 'http://chart.apis.google.com/chart';
/**
* helpers
*
* @var array
*/
var $helpers = array('Html');
/**
* Default options
*
* @var array
*/
var $__defaults = array('width' => 440,
'height' => 180,
'useLegend' => true,
'scaleType' => 'y');
/**
* The line chart is output.
*
* @param array $data
* @param array $labels
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function line($data, $labels = array(), $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, $options);
$query = $this->__generateQuery('lc', $data, $labels, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The x and y axis line chart is output.
*
* @param array $data
* @param array $labels
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function xyline($data, $labels = array(), $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, array('scaleType' => 'xyn'), $options);
$query = $this->__generateQuery('lxy', $data, $labels, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Spark line chart is output.
*
* @param array $data
* @param array $labels
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function sparkline($data, $labels = array(), $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, $options);
$query = $this->__generateQuery('ls', $data, $labels, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Vertical bar chart is output.
*
* @param array $data
* @param array $labels
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function vbar($data, $labels = array(), $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, array('barType' => 'group'), $options);
if ($this->__isAssociationArray($data) && empty($labels['x'])) {
$labels['x'] = null;
}
if ($options['barType'] === 'single') {
$query = $this->__generateQuery('bvs', $data, $labels, $options, $extra);
} else {
$query = $this->__generateQuery('bvg', $data, $labels, $options, $extra);
}
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Horizontal bar chart is output.
*
* @param array $data
* @param array $labels
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function hbar($data, $labels = array(), $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, array('barType' => 'group', 'scaleTyle' => 'x'), $options);
if ($this->__isAssociationArray($data) && empty($labels['y'])) {
$labels['y'] = null;
}
if ($options['barType'] === 'single') {
$query = $this->__generateQuery('bhs', $data, $labels, $options, $extra);
} else {
$query = $this->__generateQuery('bhg', $data, $labels, $options, $extra);
}
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Pie chart is output.
*
* @param array $data
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function pie($data, $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, $options);
$query = $this->__generateQuery('p', $data, null, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The 3D pie chart is output.
*
* @param array $data
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function pie3d($data, $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, $options);
$query = $this->__generateQuery('p3', $data, null, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Venn diagram is output.
*
* @param array $data
* @param array $intersections
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function venn($data, $intersections, $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, array('intersections' => $intersections), $options);
$query = $this->__generateQuery('v', $data, null, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Scatter chart is output.
*
* @param array $data
* @param array $labels
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function scatter($data, $labels = array(), $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults,
array('shapeMarker' => array(array(array('o', 'ff0000', '-1', 50))),
'scaleType' => 'xy'), $options);
$query = $this->__generateQuery('s', $data, $labels, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Radar chart is output.
*
* @param array $data
* @param array $labels
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function radar($data, $labels = array(), $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, $options);
$query = $this->__generateQuery('r', $data, $labels, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Map is output.
*
* @param array $data
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function map($data, $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, array('area' => 'world', 'bg' => 'EAF7FE'), $options);
$query = $this->__generateQuery('t', $data, null, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The Google-o-meter is output.
*
* @param string $text
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function meter($data, $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, array('useLegend' => false), $options);
$query = $this->__generateQuery('gom', $data, null, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The QR code is output.
*
* @param string $text
* @param array $options
* @param array $extra
* @param array $attributes
* @return string
*/
function qr($text, $options = array(), $extra = array(), $attributes = array())
{
$options = am($this->__defaults, $options);
$query = $this->__generateQuery('qr', $text, null, $options, $extra);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* The parameter is input directly.
*
* @param array $query
* @param array $attributes
* @return string
*/
function api($query, $attributes = array())
{
$query = Router::queryString($query);
return $this->Html->image($this->googleChartApi . $query, $attributes);
}
/**
* Set Defaults Param.
*
* @param array $defaults
*/
function setDefaults($defaults = array())
{
$this->__defaults = am($this->__defaults, $defaults);
}
/**
* Get query is generated.
*
* @param string $type
* @param array $data
* @param array $labels
* @param array $options
* @param array $extra
* @return string
* @access private
*/
function __generateQuery($type, $data, $labels = array(), $options = array(), $extra = array())
{
$query['cht'] = $type;
$query['chs'] = "{$options['width']}x{$options['height']}";
if (is_array($data) && !empty($labels)) {
$query['chxt'] = join(',', array_keys($labels));
$labelIndex = 0;
foreach ($labels as $labelKey => $labelVal) {
if (($labelKey === 'x' && ($type === 'bvs' || $type === 'bvg')) ||
($labelKey === 'y' && ($type === 'bhs' || $type === 'bhg'))) {
if ($this->__isAssociationArray($data)) {
$labelVal = array_keys($data);
}
}
if (!empty($labelVal)) {
if (!$this->__isAssociationArray($labelVal)) {
$labelValues[] = "{$labelIndex}:|" . join('|', $labelVal);
} else {
$labelValues[] = "{$labelIndex}:|" . join('|', array_keys($labelVal));
$labelPositions[] = "{$labelIndex}," . join(',', $labelVal);
}
}
if (!empty($options['range'][$labelKey])) {
$labelRanges[] = "{$labelIndex},{$options['range'][$labelKey][0]},{$options['range'][$labelKey][1]}";
}
if (!empty($options['labelStyle'][$labelKey])) {
$labelStyles[] = "{$labelIndex},{$options['labelStyle'][$labelKey]['color']},{$options['labelStyle'][$labelKey]['size']}";
}
$labelIndex ++;
}
if (!empty($options['unit']) && is_array($options['unit'])) {
foreach ($options['unit'] as $unitKey => $unitVal) {
$query['chxt'] .= ",{$unitKey}";
$labelValues[] = "{$labelIndex}:|({$unitVal})";
$labelIndex ++;
}
}
if (!empty($labelValues)) {
$query['chxl'] = join('|', $labelValues);
}
if (!empty($labelPositions)) {
$query['chxp'] = join('|', $labelPositions);
}
if (!empty($labelRanges)) {
$query['chxr'] = join('|', $labelRanges);
}
if (!empty($labelStyles)) {
$query['chxs'] = join('|', $labelStyles);
}
}
switch ($type) {
case 'lc':
case 'ls':
foreach ($data as $lineVal) {
if (is_array($lineVal)) {
$lineVals[] = join(',', $lineVal);
}
}
if (empty($lineVals)) {
$lineVals[] = join(',', $data);
}
$query['chd'] = 't:' . join('|', $lineVals);
$chm = 'b';
break;
case 'lxy':
foreach ($data as $lineVal) {
if (is_array($lineVal)) {
$lineVals[] = join(',', $lineVal[0]);
$lineVals[] = join(',', $lineVal[1]);
}
}
if (empty($lineVals)) {
$lineVals[] = join(',', $data);
}
$query['chd'] = 't:' . join('|', $lineVals);
$chm = 'b';
break;
case 'bvs':
case 'bhs':
case 'bvg':
case 'bhg':
$dataSets = array();
foreach ($data as $barVal) {
if (is_array($barVal)) {
for ($i = 0; $i < count($barVal); $i ++) {
$dataSets[$i][] = $barVal[$i];
}
}
}
for ($i = 0; $i < count($dataSets); $i ++) {
$dataSets[$i] = join(',', $dataSets[$i]);
}
if (empty($dataSets)) {
$dataSets[] = join(',', $data);
}
$query['chd'] = 't:' . join('|', $dataSets);
break;
case 'p':
case 'p3':
if (!empty($options['unit'])) {
$unit = $options['unit'];
} else {
$unit = '';
}
if ($options['useLegend'] && !empty($options['color'])) {
$query['chl'] = join("{$unit}|", $data) . $unit;
} else {
foreach ($data as $key => $val) {
$dataKeys[] = "{$key}({$val}{$unit})";
}
$query['chl'] = join("|", $dataKeys);
}
$query['chd'] = 't:' . join(',', $data);
break;
case 'v':
$query['chd'] = 't:' . join(',', am($data, $options['intersections']));
break;
case 's':
$dataSets = array();
foreach ($data as $stVal) {
if (is_array($stVal)) {
for ($i = 0; $i < count($stVal); $i ++) {
$dataSets[$i][] = $stVal[$i];
}
}
}
for ($i = 0; $i < count($dataSets); $i ++) {
$dataSets[$i] = join(',', $dataSets[$i]);
}
if (empty($dataSets)) {
$dataSets[] = join(',', $data);
}
$query['chd'] = 't:' . join('|', $dataSets);
if ($this->__isAssociationArray($data)) {
$stIndex = 0;
foreach ($data as $stKey => $stVal) {
$stTextColor = '000000';
if (!empty($options['shapeMarker'])) {
if (!empty($options['shapeMarker'][0][$stIndex])) {
$stTextColor = $options['shapeMarker'][0][$stIndex][1];
} else {
foreach ($options['shapeMarker'][0] as $shapeMarkerVal) {
if ($shapeMarkerVal[2] == -1) {
$stTextColor = $shapeMarkerVal[1];
}
}
}
}
$stTextSize = $stVal[2] / 1.5;
$stTexts[] = "t{$stKey},{$stTextColor},0,{$stIndex},{$stTextSize},0";
$stIndex ++;
}
}
break;
case 'r':
foreach ($data as $radarVal) {
if (is_array($radarVal)) {
$radatVal[] = $radarVal[0];
$radarVals[] = join(',', $radarVal);
}
}
if (empty($radarVals)) {
$data[] = $data[0];
$radarVals[] = join(',', $data);
}
$query['chd'] = 't:' . join('|', $radarVals);
$chm = 'B';
break;
case 't':
$query['chtm'] = $options['area'];
$query['chld'] = join('', array_keys($data));
$query['chd'] = 's:' . join('', $data);
break;
case 'gom':
$query['chl'] = join('|', array_keys($data));
$query['chd'] = 't:' . join(',', $data);
break;
case 'qr':
$query['chl'] = $data;
break;
}
// Data Scale
switch ($options['scaleType']) {
case 'x':
if (!empty($options['range']['x'])) {
$query['chds'] = join(',', $options['range']['x']);
}
break;
case 'y':
if (!empty($options['range']['y'])) {
$query['chds'] = join(',', $options['range']['y']);
}
break;
case 'xy';
if (!empty($options['range'])) {
$scaleValues = array();
if (!empty($options['range']['x'])) {
$scaleValues[] = join(',', $options['range']['x']);
} else {
$scaleValues[] = '0,100';
}
if (!empty($options['range']['y'])) {
$scaleValues[] = join(',', $options['range']['y']);
} else {
$scaleValues[] = '0,100';
}
$scaleValues[] = '0,100';
$query['chds'] = join(',', $scaleValues);
}
break;
case 'xyn';
if (!empty($options['range'])) {
$scaleValues = array();
if (!empty($options['range']['x'])) {
$scaleX = join(',', $options['range']['x']);
} else {
$scaleX = '0,100';
}
if (!empty($options['range']['y'])) {
$scaleY = join(',', $options['range']['y']);
} else {
$scaleY = '0,100';
}
$dataset = explode('|', $query['chd']);
for ($i = 0; $i < count($dataset); $i += 2) {
$scaleValues[] = $scaleX;
$scaleValues[] = $scaleY;
}
$query['chds'] = join(',', $scaleValues);
}
break;
}
// Chart colors and legend
if (!empty($options['color'])) {
if (is_array($options['color'])) {
if ($options['useLegend']) {
if (!$this->__isAssociationArray($options['color'])) {
$query['chdl'] = join('|', array_keys($data));
} else {
$query['chdl'] = join('|', array_keys($options['color']));
}
}
if (!empty($options['legendPosition'])) {
$query['chdlp'] = substr($options['legendPosition'], 0, 1);
}
$query['chco'] = join(',', $options['color']);
} else {
$query['chco'] = $options['color'];
}
}
// Solid fill and Linear gradient and Linear stripes
if (!empty($options['bg'])) {
if (is_array($options['bg'])) {
foreach ($options['bg'] as $bgKey => $bgVal) {
if ($bgKey === 'chart') {
$bgKey = 'c';
} else if ($bgKey === 'alpha') {
$bgKey = 'a';
}
switch ($bgVal[0]) {
case 'solid':
$bgValues[] = "{$bgKey},s,{$bgVal[1]}";
break;
case 'gradient':
$bgValues[] = "{$bgKey},lg,{$bgVal[1]},{$bgVal[2]},0,{$bgVal[3]},1";
break;
case 'stripes':
foreach ($bgVal[2] as $stripeColor => $stripeWidth) {
$stripeValues[] = "{$stripeColor},{$stripeWidth}";
}
$stripe = join(',', $stripeValues);
$bgValues[] = "{$bgKey},ls,{$bgVal[1]},{$stripe}";
break;
}
}
$query['chf'] = join('|', $bgValues);
} else {
$query['chf'] = "bg,lg,90,{$options['bg']},0,FFFFFF,1";
}
}
// Fill area
if (!empty($options['fill']) && !empty($chm)) {
if (is_array($options['fill'])) {
foreach ($options['fill'] as $fillKey => $fill) {
$sindex = $fillKey;
$eindex = $fillKey + 1;
$fills[] = "{$chm},{$fill},{$sindex},{$eindex},0";
}
$query['chm'] = join('|', $fills);
} else {
$query['chm'] = "B,{$options['fill']},0,0,0";
}
}
// Chart title
if (!empty($options['title'])) {
if (is_array($options['title'])) {
$query['chtt'] = $options['title']['title'];
$query['chts'] = "{$options['title']['color']},{$options['title']['size']}";
} else {
$query['chtt'] = $options['title'];
}
}
// Grid lines
if (!empty($options['grid'])) {
$query['chg'] = join(',', $options['grid']);
}
// Bar width and spacing
if (!empty($options['barStyle'])) {
$query['chbh'] = join(',', $options['barStyle']);
}
// Bar chart zero line
if (!empty($options['barZeroPosition'])) {
$query['chp'] = $options['barZeroPosition'];
}
// Line chart styles
if (!empty($options['lineStyle'])) {
foreach ($options['lineStyle'] as $lineStyleKey => $lineStyleVal) {
$lineStyleValues[] = join(',', $lineStyleVal);
}
$query['chls'] = join('|', $lineStyleValues);
}
// Line and bar chart line styles
if (!empty($options['lineWidth'])) {
if (!empty($options['color'])) {
$colors = array_values($options['color']);
}
foreach ($options['lineWidth'] as $lineWidthKey => $lineWidthVal) {
if (empty($lineWidthVal)) {
continue;
}
if (!empty($colors[$lineWidthKey])) {
$color = $colors[$lineWidthKey];
} else {
$color = '000000';
}
if (is_array($lineWidthVal)) {
$width = $lineWidthVal[0];
$priority = $lineWidthVal[1];
} else {
$width = $lineWidthVal;
$priority = 0;
}
$lineWidthValues[] = "D,{$color},{$lineWidthKey},0,{$width},{$priority}";
}
if (!empty($query['chm'])) {
$lineWidthValues[] = $query['chm'];
}
$query['chm'] = join('|', $lineWidthValues);
}
// Shape markers
if (!empty($options['shapeMarker'])) {
foreach ($options['shapeMarker'] as $shapeMarkerKey => $shapeMarkerVal) {
foreach ($shapeMarkerVal as $shapeMarker) {
$markerType = substr($shapeMarker[0], 0, 1);
if ($markerType === 't') {
$markerText = $shapeMarker[1];
$markerColor = $shapeMarker[2];
$markerPoint = $shapeMarker[3];
$markerSize = $shapeMarker[4];
if (!empty($shapeMarker[5])) {
$markerPriority = $shapeMarker[5];
} else {
$markerPriority = 0;
}
$shapeMarkerValues[] = "{$markerType}{$markerText},{$markerColor},{$shapeMarkerKey},{$markerPoint},{$markerSize},{$markerPriority}";
} else {
$markerColor = $shapeMarker[1];
$markerPoint = $shapeMarker[2];
$markerSize = $shapeMarker[3];
if (!empty($shapeMarker[4])) {
$markerPriority = $shapeMarker[4];
} else {
$markerPriority = 0;
}
$shapeMarkerValues[] = "{$markerType},{$markerColor},{$shapeMarkerKey},{$markerPoint},{$markerSize},{$markerPriority}";
}
}
}
if (!empty($query['chm'])) {
$shapeMarkerValues[] = $query['chm'];
}
$query['chm'] = join('|', $shapeMarkerValues);
}
if (!empty($stTexts)) {
if (!empty($query['chm'])) {
$query['chm'] = $query['chm'] . '|' . join('|', $stTexts);
} else {
$query['chm'] = join('|', $stTexts);
}
}
// Range markers
if (!empty($options['rangeMarker'])) {
foreach ($options['rangeMarker'] as $rangeMarkerKey => $rangeMarkerVal) {
if (is_array($rangeMarkerVal)) {
$markerType = $ramgeMarkerVal[0];
if ($markerType === 'h') {
$markerType = 'r';
} else if ($markerType === 'v') {
$markerType = 'R';
}
$markerColor = $ramgeMarkerVal[1];
$markerStart = $ramgeMarkerVal[2];
$markerEnd = $ramgeMarkerVal[3];
$rangeMarkerValues[] = "$markerType,$markerColor,0,$markerStart,$markerEnd";
}
}
if (empty($rangeMarkerValues)) {
$markerType = $options['rangeMarker'][0];
if ($markerType === 'h') {
$markerType = 'r';
} else if ($markerType === 'v') {
$markerType = 'R';
}
$markerColor = $options['rangeMarker'][1];
$markerStart = $options['rangeMarker'][2];
$markerEnd = $options['rangeMarker'][3];
$rangeMarkerValues[] = "$markerType,$markerColor,0,$markerStart,$markerEnd";
}
if (!empty($query['chm'])) {
$rangeMarkerValues[] = $query['chm'];
}
$query['chm'] = join('|', $rangeMarkerValues);
}
return Router::queryString(am($query, $extra));
}
/**
* It is examined whether the specified array is an associative array.
*
* @param array $array
* @return boolean Association array is true.
* @access private
*/
function __isAssociationArray($array)
{
if (count($array) === 1) {
if (key($array) === 0) {
return false;
} else {
return true;
}
} else {
if (array_keys($array) === range(0, count($array) - 1)) {
return false;
} else {
return true;
}
}
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment