Merge branch 'QA_3_4'
[phpmyadmin-regexreplace.git] / libraries / chart / pma_pchart_chart.php
blobc4277d80463868bc142049b955f5b8b31d399da9
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Holds the base class that all charts using pChart inherit from and some
5 * widely used constants
6 * @package phpMyAdmin
7 */
9 /**
12 define('TOP', 0);
13 define('RIGHT', 1);
14 define('BOTTOM', 2);
15 define('LEFT', 3);
17 require_once 'pma_chart.php';
19 require_once 'pChart/pData.class';
20 require_once 'pChart/pChart.class';
22 /**
23 * Base class for every chart implemented using pChart.
24 * @abstract
25 * @package phpMyAdmin
27 abstract class PMA_pChart_chart extends PMA_chart
29 /**
30 * @var String title text
32 protected $titleText;
34 /**
35 * @var array data for the chart
37 protected $data;
39 /**
40 * @var object pData object that holds the description of the data
42 protected $dataSet;
44 /**
45 * @var object pChart object that holds the chart
47 protected $chart;
49 /**
50 * @var array holds base64 encoded chart image parts
52 protected $partsEncoded = array();
54 public function __construct($data, $options = null)
56 parent::__construct($options);
58 $this->data = $data;
60 $this->settings['fontPath'] = './libraries/chart/pChart/fonts/';
62 $this->settings['scale'] = SCALE_ADDALLSTART0;
64 $this->settings['labelHeight'] = 20;
66 $this->settings['fontSize'] = 8;
68 $this->settings['continuous'] = 'off';
70 // as in CSS (top, right, bottom, left)
71 $this->setAreaMargins(array(20, 20, 40, 60));
73 // Get color settings from theme
74 $this->settings = array_merge($this->settings,$GLOBALS['cfg']['chartColor']);
77 protected function init()
79 parent::init();
81 // create pChart object
82 $this->chart = new pChart($this->getWidth(), $this->getHeight());
84 // create pData object
85 $this->dataSet = new pData;
87 $this->chart->reportWarnings('GD');
88 $this->chart->ErrorFontName = $this->getFontPath().'DejaVuSans.ttf';
90 // initialize colors
91 foreach ($this->getColors() as $key => $color) {
92 $this->chart->setColorPalette(
93 $key,
94 hexdec(substr($color, 1, 2)),
95 hexdec(substr($color, 3, 2)),
96 hexdec(substr($color, 5, 2))
100 $this->chart->setFontProperties($this->getFontPath().'DejaVuSans.ttf', $this->getFontSize());
102 $this->chart->setImageMap(true, 'mapid');
106 * data is put to the $dataSet object according to what type chart is
107 * @abstract
109 abstract protected function prepareDataSet();
112 * all components of the chart are drawn
114 protected function prepareChart()
116 $this->drawBackground();
117 $this->drawChart();
121 * draws the background
123 protected function drawBackground()
125 $this->drawCommon();
126 $this->drawTitle();
127 $this->setGraphAreaDimensions();
128 $this->drawGraphArea();
132 * draws the part of the background which is common to most of the charts
134 protected function drawCommon()
136 $this->chart->drawGraphAreaGradient(
137 $this->getBgColor(RED),
138 $this->getBgColor(GREEN),
139 $this->getBgColor(BLUE),
140 // With a gradientIntensity of 0 the background does't draw, oddly
141 ($this->settings['gradientIntensity']==0)?1:$this->settings['gradientIntensity'],TARGET_BACKGROUND);
143 if(is_string($this->settings['border']))
144 $this->chart->addBorder(1,$this->getBorderColor(RED),$this->getBorderColor(GREEN),$this->getBorderColor(BLUE));
148 * draws the chart title
150 protected function drawTitle()
152 // Draw the title
153 $this->chart->drawTextBox(
156 $this->getWidth(),
157 $this->getLabelHeight(),
158 $this->getTitleText(),
160 $this->getTitleColor(RED),
161 $this->getTitleColor(GREEN),
162 $this->getTitleColor(BLUE),
163 ALIGN_CENTER,
164 false,
165 $this->getTitleBgColor(RED),
166 $this->getTitleBgColor(GREEN),
167 $this->getTitleBgColor(BLUE)
172 * calculates and sets the dimensions that will be used for the actual graph
174 protected function setGraphAreaDimensions()
176 $this->chart->setGraphArea(
177 $this->getAreaMargin(LEFT),
178 $this->getLabelHeight() + $this->getAreaMargin(TOP),
179 $this->getWidth() - $this->getAreaMargin(RIGHT),
180 $this->getHeight() - $this->getAreaMargin(BOTTOM)
185 * draws graph area (the area where all bars, lines, points will be seen)
187 protected function drawGraphArea()
189 $this->chart->drawGraphArea(
190 $this->getGraphAreaColor(RED),
191 $this->getGraphAreaColor(GREEN),
192 $this->getGraphAreaColor(BLUE),
193 FALSE
195 $this->chart->drawScale(
196 $this->dataSet->GetData(),
197 $this->dataSet->GetDataDescription(),
198 $this->getScale(),
199 $this->getScaleColor(RED),
200 $this->getScaleColor(GREEN),
201 $this->getScaleColor(BLUE),
202 TRUE,0,2,TRUE
205 if($this->settings['gradientIntensity']>0)
206 $this->chart->drawGraphAreaGradient(
207 $this->getGraphAreaGradientColor(RED),
208 $this->getGraphAreaGradientColor(GREEN),
209 $this->getGraphAreaGradientColor(BLUE),
210 $this->settings['gradientIntensity']
212 else
213 $this->chart->drawGraphArea(
214 $this->getGraphAreaGradientColor(RED),
215 $this->getGraphAreaGradientColor(GREEN),
216 $this->getGraphAreaGradientColor(BLUE)
219 $this->chart->drawGrid(
221 TRUE,
222 $this->getGridColor(RED),
223 $this->getGridColor(GREEN),
224 $this->getGridColor(BLUE),
230 * draws the chart
231 * @abstract
233 protected abstract function drawChart();
236 * Renders the chart, base 64 encodes the output and puts it into
237 * array partsEncoded.
239 * Parameter can be used to slice the chart vertically into parts. This
240 * solves an issue where some browsers (IE8) accept base64 images only up
241 * to some length.
243 * @param integer $parts number of parts to render.
244 * Default value 1 means that all the
245 * chart will be in one piece.
247 protected function render($parts = 1)
249 $fullWidth = 0;
251 for ($i = 0; $i < $parts; $i++) {
253 // slicing is vertical so part height is the full height
254 $partHeight = $this->chart->YSize;
256 // there will be some rounding erros, will compensate later
257 $partWidth = round($this->chart->XSize / $parts);
258 $fullWidth += $partWidth;
259 $partX = $partWidth * $i;
261 if ($i == $parts - 1) {
262 // if this is the last part, compensate for the rounding errors
263 $partWidth += $this->chart->XSize - $fullWidth;
266 // get a part from the full chart image
267 $part = imagecreatetruecolor($partWidth, $partHeight);
268 imagecopy($part, $this->chart->Picture, 0, 0, $partX, 0, $partWidth, $partHeight);
270 // render part and save it to variable
271 ob_start();
272 imagepng($part, NULL, 9, PNG_ALL_FILTERS);
273 $output = ob_get_contents();
274 ob_end_clean();
276 // base64 encode the current part
277 $partEncoded = base64_encode($output);
278 $this->partsEncoded[$i] = $partEncoded;
283 * get the HTML and JS code for the configured chart
284 * @return string HTML and JS code for the chart
286 public function toString()
288 if (!function_exists('gd_info')) {
289 array_push($this->errors, ERR_NO_GD);
290 return '';
293 $this->init();
294 $this->prepareDataSet();
295 $this->prepareChart();
297 //$this->chart->debugImageMap();
298 //$this->chart->printErrors('GD');
300 // check if a user wanted a chart in one part
301 if ($this->isContinuous()) {
302 $this->render(1);
304 else {
305 $this->render(20);
308 $returnData = '<div id="chart">';
309 foreach ($this->partsEncoded as $part) {
310 $returnData .= '<img src="data:image/png;base64,'.$part.'" />';
312 $returnData .= '</div>';
314 // add tooltips only if json is available
315 if (function_exists('json_encode')) {
316 $returnData .= '
317 <script type="text/javascript">
318 //<![CDATA[
319 imageMap.loadImageMap(\''.json_encode($this->getImageMap()).'\');
320 //]]>
321 </script>
324 else {
325 array_push($this->errors, ERR_NO_JSON);
328 return $returnData;
331 protected function getLabelHeight()
333 return $this->settings['labelHeight'];
336 protected function setAreaMargins($areaMargins)
338 $this->settings['areaMargins'] = $areaMargins;
341 protected function getAreaMargin($side)
343 return $this->settings['areaMargins'][$side];
346 protected function getFontPath()
348 return $this->settings['fontPath'];
351 protected function getScale()
353 return $this->settings['scale'];
356 protected function getFontSize()
358 return $this->settings['fontSize'];
361 protected function isContinuous()
363 return $this->settings['continuous'] == 'on';
366 protected function getImageMap()
368 return $this->chart->getImageMap();
371 protected function getGraphAreaColor($component)
373 return $this->hexStrToDecComp($this->settings['graphAreaColor'], $component);
376 protected function getGraphAreaGradientColor($component)
378 return $this->hexStrToDecComp($this->settings['graphAreaGradientColor'], $component);
381 protected function getGridColor($component)
383 return $this->hexStrToDecComp($this->settings['gridColor'], $component);
386 protected function getScaleColor($component)
388 return $this->hexStrToDecComp($this->settings['scaleColor'], $component);
391 protected function getTitleBgColor($component)
393 return $this->hexStrToDecComp($this->settings['titleBgColor'], $component);
396 protected function getBorderColor($component)
398 return $this->hexStrToDecComp($this->settings['border'], $component);