Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit 55e52e72a7b07553efcce7835b527a0ebd6dfb76 @samdark samdark committed Jan 30, 2012
Showing with 564 additions and 0 deletions.
  1. +118 −0 BarChart.php
  2. +124 −0 BaseChart.php
  3. +119 −0 PieChart.php
  4. +38 −0 assets/charts.js
  5. +7 −0 assets/g.bar-min.js
  6. +7 −0 assets/g.dot-min.js
  7. +7 −0 assets/g.line-min.js
  8. +1 −0 assets/g.pie-min.js
  9. +7 −0 assets/g.raphael-min.js
  10. +8 −0 assets/raphael-min.js
  11. +4 −0 changelog.md
  12. +124 −0 readme.md
@@ -0,0 +1,118 @@
+<?php
+require_once 'BaseChart.php';
+/**
+ * Bar chart widget
+ *
+ * @author Dmytro Zasyadko
+ * @version 1.0
+ */
+class BarChart extends BaseChart
+{
+
+ /**
+ * @var array Chart data. Valid format is the following:
+ * array(
+ * array(10,20,30),
+ * array(30, 20, 50),
+ * array(20, 80, 10),
+ * array(15, 25, 35),
+ * )
+ */
+ public $data;
+
+ /**
+ * @var string Type of the chart. Can be either 'vertical' or 'horizontal'. Default is
+ * 'vertical'.
+ */
+ public $chartType='vertical';
+
+ /**
+ * @var boolean If chart bars should be stacked. Default is false.
+ */
+ public $stacked=false;
+
+ /**
+ * @var string Type of chart bars. Can be 'soft', 'round', 'sharp' or 'square'.
+ * Default is 'soft'.
+ */
+ public $barType='soft';
+
+ /**
+ * @var string Gutter width. Default is '20%'.
+ */
+ public $gutterWidth='20%';
+
+ /**
+ * @var array Default chart configuration.
+ */
+ protected $_defaultOptions=array(
+ 'top'=>10,
+ 'left'=>10,
+ 'width'=>300,
+ 'height'=>220,
+ );
+
+ /**
+ * Initializes the widget.
+ * This method is called by {@link CBaseController::createWidget}
+ * and {@link CBaseController::beginWidget} after the widget's
+ * properties have been initialized.
+ */
+ public function init()
+ {
+ parent::init();
+ $this->_defaultHtmlOptions=array(
+ 'id'=>$this->getId(),
+ );
+ }
+
+ /**
+ * Creates initial script for the chart
+ * @return string
+ */
+ protected function createInitScript()
+ {
+ parent::createInitScript();
+
+ $chartData=$this->getChartData();
+
+ $initScript="var r = Raphael('" . $this->getId() . "');";
+ if(is_array($this->label) && isset($this->label['text']))
+ {
+ $initScript.="charts.drawLabel(r, " . CJavaScript::encode($this->label['left']) . ", " . CJavaScript::encode($this->label['top']) . ", " . CJavaScript::encode($this->label['text']) . ", " . CJavaScript::encode($this->label['font']) . ");";
+ }
+ $initScript.="var chart = r." . ($this->chartType=='vertical' ? 'barchart' : 'hbarchart');
+ $initScript.="({$this->options['left']}, {$this->options['top']}, {$this->options['width']}, {$this->options['height']}, " . CJavaScript::encode($chartData) . ", {stacked: " . CJavaScript::encode($this->stacked) . ", type: " . CJavaScript::encode($this->barType) . ", gutterWidth:" . CJavaScript::encode($this->gutterWidth) . "});";
+ $initScript.="chart.hover(charts.barOver, charts.barOut);";
+ $initScript.=$this->getHandlersInit();
+ return $initScript;
+ }
+
+ /**
+ * Publishes and registers all necessary script files.
+ */
+ protected function registerScripts()
+ {
+ parent::registerScripts();
+ $basePath=dirname(__FILE__) . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR;
+ $baseUrl=Yii::app()->getAssetManager()->publish($basePath,false,1,YII_DEBUG);
+ Yii::app()->clientScript->registerScriptFile($baseUrl . '/g.bar-min.js');
+ }
+
+ /**
+ * Transforms data passed to the widget to the format required by bar chart
+ * @return array chart data
+ */
+ private function getChartData()
+ {
+ $result=array();
+ foreach($this->data as $rowIndex=>$dataRow)
+ {
+ foreach($dataRow as $itemIndex=>$dataItem)
+ {
+ $result[$itemIndex][$rowIndex]=$dataItem;
+ }
+ }
+ return $result;
+ }
+}
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Base for all chart widgets.
+ *
+ * @author Dmytro Zasyadko
+ * @version 1.0
+ */
+class BaseChart extends CWidget
+{
+ /**
+ * @var array Main chart configuration (it's different for different charts).
+ */
+ public $options=array();
+
+ /**
+ * @var array Set of JavaScript event handlers for chart
+ */
+ public $eventHandlers=array();
+
+ /**
+ * @var array Additional HTML options to be rendered in the input tag.
+ */
+ public $htmlOptions=array();
+
+ /**
+ * @var array Labels config for chart.
+ *
+ * Correct format is:
+ *
+ * array(
+ * 'left'=>160,
+ * 'top'=>10,
+ * 'text'=>'Simple Pie Chart',
+ * 'font'=>'12px sans-serif',
+ * )
+ *
+ * 'left' and 'top' attributes could be 'auto'.
+ */
+ public $label=array();
+
+ /**
+ * Initializes the widget.
+ * This method is called by {@link CBaseController::createWidget}
+ * and {@link CBaseController::beginWidget} after the widget's
+ * properties have been initialized.
+ */
+ public function init()
+ {
+ parent::init();
+ $this->registerScripts();
+ $this->label=array_merge(array(
+ 'left'=>'auto',
+ 'top'=>'auto',
+ 'font'=>'12px sans-serif',
+ ),$this->label);
+ }
+
+ /**
+ * @var array Default HTML options to be rendered in the input tag.
+ */
+ protected $_defaultHtmlOptions=array();
+
+ /**
+ * @var array Default chart configuration.
+ */
+ protected $_defaultOptions=array();
+
+ /**
+ * Renders the widget.
+ */
+ public function run()
+ {
+ $this->htmlOptions=CMap::mergeArray($this->_defaultHtmlOptions,$this->htmlOptions);
+ $this->options=CMap::mergeArray($this->_defaultOptions,$this->options);
+ echo CHtml::openTag('div',$this->htmlOptions);
+ echo CHtml::closeTag('div');
+
+ Yii::app()->clientScript->registerScript(__CLASS__.'#'.$this->getId(),$this->createInitScript());
+ }
+
+ /**
+ * Publishes and registers all necessary script files.
+ */
+ protected function registerScripts()
+ {
+ $basePath=dirname(__FILE__) . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR;
+ $baseUrl=Yii::app()->getAssetManager()->publish($basePath,false,1,YII_DEBUG);
+
+ $cs=Yii::app()->clientScript;
+ $cs->registerCoreScript('jquery');
+ $cs->registerScriptFile($baseUrl.'/raphael-min.js');
+ $cs->registerScriptFile($baseUrl.'/g.raphael-min.js');
+ $cs->registerScriptFile($baseUrl.'/charts.js');
+ }
+
+ /**
+ * Base function for creating initial JavaScript.
+ * @return string
+ */
+ protected function createInitScript()
+ {
+ }
+
+ /**
+ * Create and return string of JavaScript code for binding events to chart
+ *
+ * @param string $chartVarName Name of JavaScript variable that contain link to the chart. Default is 'chart'.
+ * @return string
+ */
+ protected function getHandlersInit($chartVarName='chart')
+ {
+ $result=null;
+ if(count($this->eventHandlers)>0)
+ {
+ $result=$chartVarName;
+ foreach($this->eventHandlers as $handlerName=>$handlerFunction)
+ {
+ $result.='.' . $handlerName . '(' . (is_array($handlerFunction) ? implode(',',$handlerFunction) : $handlerFunction) . ')';
+ }
+ $result.=';';
+ }
+ return $result;
+ }
+}
@@ -0,0 +1,119 @@
+<?php
+require_once 'BaseChart.php';
+/**
+ * Pie chart widget
+ *
+ * @author Dmytro Zasyadko
+ * @version 1.0
+ */
+class PieChart extends BaseChart
+{
+
+ /**
+ * @var array Chart data. Valid format is the following:
+ *
+ * array(
+ * array('legend'=>'Param1', 'value'=>10, 'href'=>'http://google.com'),
+ * array('legend'=>'Param2', 'value'=>20, 'href'=>''),
+ * array('legend'=>'Param3', 'value'=>30, 'href'=>null),
+ * array('legend'=>'Param4', 'value'=>40, 'href'=>null),
+ * )
+ */
+ public $data;
+
+ /**
+ * @var string Legend position. Can be 'east', 'west', 'north' or 'south'.
+ * Default is 'west'.
+ */
+ public $legendPosition='west';
+
+ /**
+ * @var array Default chart configuration.
+ */
+ protected $_defaultOptions=array(
+ 'centerTop'=>100,
+ 'centerLeft'=>100,
+ 'radius'=>100
+ );
+
+ /**
+ * Initializes the widget.
+ * This method is called by {@link CBaseController::createWidget}
+ * and {@link CBaseController::beginWidget} after the widget's
+ * properties have been initialized.
+ */
+ public function init()
+ {
+ parent::init();
+ usort($this->data,array($this,"compare"));
+ $this->_defaultHtmlOptions=array(
+ 'id'=>$this->getId(),
+ );
+ }
+
+ /**
+ * Creates initial script for the chart
+ * @return string
+ */
+ protected function createInitScript()
+ {
+ parent::createInitScript();
+
+ $chartData=$this->getChartData();
+
+ $initScript="var r = Raphael('" . $this->getId() . "');";
+ if(is_array($this->label) && isset($this->label['text']))
+ {
+ $initScript.="charts.drawLabel(r, " . CJavaScript::encode($this->label['left']) . ", " . CJavaScript::encode($this->label['top']) . ", " . CJavaScript::encode($this->label['text']) . ", " . CJavaScript::encode($this->label['font']) . ");";
+ }
+ $initScript.="var chart = r.piechart({$this->options['centerLeft']}, {$this->options['centerTop']}, {$this->options['radius']}," . CJavaScript::encode($chartData['values']) . ", { legend: " . CJavaScript::encode($chartData['legends']) . ", legendpos: '$this->legendPosition', href: " . CJavaScript::encode($chartData['hrefs']) . "});";
+ $initScript.="chart.hover(charts.pieOver, charts.pieOut);";
+ $initScript.=$this->getHandlersInit();
+ return $initScript;
+ }
+
+ /**
+ * Publishes and registers all necessary script files.
+ */
+ protected function registerScripts()
+ {
+ parent::registerScripts();
+ $basePath=dirname(__FILE__) . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR;
+ $baseUrl=Yii::app()->getAssetManager()->publish($basePath,false,1,YII_DEBUG);
+ Yii::app()->clientScript->registerScriptFile($baseUrl . '/g.pie-min.js');
+ }
+
+ /**
+ * Transforms data passed to the widget to the format required by pie chart
+ * @return array chart data
+ */
+ private function getChartData()
+ {
+ $result=array('legends'=>array(),'values'=>array(),'hrefs'=>array());
+ foreach($this->data as $dataRow)
+ {
+ $result['legends'][]=$dataRow['legend'];
+ $result['values'][]=$dataRow['value'];
+ $result['hrefs'][]=$dataRow['href'];
+ }
+ return $result;
+ }
+
+ /**
+ * Used by usort for sorting data arrays by value
+ * @static
+ *
+ * @param $a array data 1
+ * @param $b array data 2
+ *
+ * @return int -1 if data 1 < data 2, 0 if data 1 == data 2, 1 if data 1 > data 2
+ */
+ static private function compare($a,$b)
+ {
+ if($a['value']==$b['value'])
+ {
+ return 0;
+ }
+ return ($a['value']>$b['value']) ? -1 : 1;
+ }
+}
Oops, something went wrong.

0 comments on commit 55e52e7

Please sign in to comment.