oTrans = new OX_Translation(); $gdAvailable = extension_loaded('gd'); $this->draw = $gdAvailable && !empty($aParams['draw']); $this->setDummyData(); $this->oTpl = new OA_Admin_Template($this->draw ? 'passthrough.html' : 'dashboard/graph.html'); $this->oTpl->setCacheId($this->getCacheId()); $this->oTpl->assign('extensionLoaded', $gdAvailable); } function getCacheId() { // Cache the graphs for each locale. return array(OX_getHostName(), get_class($this), $GLOBALS['_MAX']['PREF']['language']); } function isDataRequired() { return $this->draw && !$this->oTpl->is_cached(); } /** * A method to set the graph data. * * @param array $aData An array with two members for impressions and clicks: * * Array * ( * [0] => Array (imps) * ( * [09-01] => 1000 * [09-02] => 1000 * [09-03] => 1000 * [09-04] => 1000 * [09-05] => 1000 * [09-06] => 1000 * [09-07] => 1000 * ) * * [1] => Array (clicks) * ( * [09-01] => 10 * [09-02] => 10 * [09-03] => 10 * [09-04] => 10 * [09-05] => 10 * [09-06] => 10 * [09-07] => 10 * ) * * ) */ function setData($aData) { if (isset($aData[0]) && is_array($aData[0]) && isset($aData[1]) && is_array($aData[1])) { for ($i = 0; $i < 2; $i++) { foreach ($aData[$i] as $k => $v) { // OXC gives us the days in english, eg Mon. $day = $this->oTrans->translate($k); $this->aData[$i][$day] = $v; } } } } /** * A method to use zeroed data to draw an empty graph * */ function setDummyData() { $this->aData = array(); for ($i = 0; $i < 7; $i++) { $day = $this->oTrans->translate(date('D', time() - 86400 * (7 - $i))); $this->aData[0][$day] = 0; $this->aData[1][$day] = 0; } } /** * A method to launch and display the widget */ function display() { if ($this->draw) { $useAntialias = is_callable('imageantialias'); $Canvas = Image_Canvas::factory('png', array( 'width' => 239, 'height' => 132, 'antialias' => $useAntialias ? 'native' : false ) ); $Graph = Image_Graph::factory('graph', $Canvas); if (is_callable('imagettftext')) { $Font = $Graph->addNew('ttf_font', MAX_PATH.'/lib/fonts/Bitstream/Vera.ttf'); $Font->setSize(7); $Graph->setFont($Font); } else { // TTF library not available, use standard bitmap font $Graph->setFontSize(7); } $Datasets = array( Image_Graph::factory('dataset'), Image_Graph::factory('dataset'), ); $Datasets[0]->setName('Impressions'); $Datasets[1]->setName('Clicks'); foreach ($this->aData[0] as $k => $v) { $Datasets[0]->addPoint($k, $v); } $scaleY2 = 1.75; $maxImpr = max($this->aData[0]); $maxClick = max($this->aData[1]); $relation = $maxImpr / ($maxClick > 0 ? $maxClick : 1); // impressions/clicks $factor = $relation / $scaleY2; //scale down to make click ~ 57% of impressions bar height foreach ($this->aData[1] as $k => $v) { $Datasets[1]->addPoint($k, $v * $factor); } $Graph->add($Plotarea = Image_Graph::factory('plotarea')); $PlotBg = Image_Graph::factory('Fill_Array'); $PlotBg->addColor('white'); $PlotFg = Image_Graph::factory('Line_Array'); $PlotFg->addColor('white'); $Plotarea->setBackground($PlotBg); $Plotarea->setBorderColor('white'); $Grid = $Plotarea->addNew('line_grid', IMAGE_GRAPH_AXIS_Y); $Grid->setLineColor('#cccccc'); $Plot = $Plotarea->addNew('bar', array($Datasets)); $Plot->setLineColor('black@0.2'); $FillArray = Image_Graph::factory('Fill_Array'); $FillArray->add(Image_Graph::factory('Fill_Gradient', array(IMAGE_GRAPH_GRAD_VERTICAL, '#b5da3c', '#6a9a2a'))); $FillArray->add(Image_Graph::factory('Fill_Gradient', array(IMAGE_GRAPH_GRAD_VERTICAL, '#bb5c9e', '#8b4a9e'))); $Plot->setFillStyle($FillArray); $AxisY2 = $Plotarea->addNew('axis', array(IMAGE_GRAPH_AXIS_Y_SECONDARY)); $AxisY2->forceMaximum(max($this->aData[1]) * $scaleY2 + 1); $AxisY = $Plotarea->getAxis(IMAGE_GRAPH_AXIS_Y); if (!max($this->aData[0])) { $AxisY->forceMaximum(1); } $func = create_function('$value', 'return OA_Dashboard_Widget_Graph::_formatY($value);'); $AxisY->setDataPreprocessor(Image_Graph::factory('Image_Graph_DataPreprocessor_Function', $func)); $AxisY2->setDataPreprocessor(Image_Graph::factory('Image_Graph_DataPreprocessor_Function', $func)); ob_start(); $Graph->done(); $content = ob_get_clean(); $this->oTpl->assign('content', $content); } else { $this->oTpl->assign('title', $this->title); $this->oTpl->assign('imageSrc', "dashboard.php?widget={$this->widgetName}&draw=1&cb=".$this->oTpl->cacheId); } $this->oTpl->display(); } /** * A method to format a value using metrics (k, M, B) * * @param float $value * @return string */ function _formatY($value) { $oTrans = new OX_Translation(); $unit = ''; $aUnits = array('B' => 1000000000, 'M' => 1000000, 'k' => 1000); foreach ($aUnits as $k => $v) { if ($value >= $v) { $value = $value / $v; $unit = $oTrans->translate($k); } } // Floats could be imprecise, round to 2 decimal before using ceil/floor, otherwise // e.g. floor($value) could return 99 even if $value seems to be 100 $value = round($value, 2); if (floor($value) != ceil($value)) { if ($value >= 100) { $digits = 0; } elseif ($value >= 10) { $digits = 1; } else { $digits = 2; } } return number_format($value, $digits, '.', ',').$unit; } } ?>