ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilChart.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once "Services/Chart/classes/class.ilChartData.php";
5 include_once "Services/Chart/classes/class.ilChartLegend.php";
6 
14 class ilChart
15 {
16  protected $id; // [string]
17  protected $renderer; // [string]
18  protected $width; // [string]
19  protected $height; // [string]
20  protected $data; // [array]
21  protected $legend; // [ilChartLegend]
22  protected $shadow; // [int]
23  protected $colors; // [array]
24  protected $ticks; // [array]
25  protected $integer_axis; // [array]
26  protected $leg_labels = array(); // [array]
27  protected $y_max = 0; // [array]
28 
37  public function __construct($a_id, $a_width = 500, $a_height = 500, $a_renderer = "flot")
38  {
39  $this->id = $a_id;
40  $this->data = array();
41  $this->setXAxisToInteger(false);
42  $this->setYAxisToInteger(false);
43  $this->setSize($a_width, $a_height);
44  $this->setRenderer($a_renderer);
45  $this->setShadow(2);
46  }
47 
53  public function setRenderer($a_value)
54  {
55  if(in_array((string)$a_value, $this->getAllRenderers()))
56  {
57  $this->renderer = (string)$a_value;
58  }
59  }
60 
66  public function getAllRenderers()
67  {
68  return array("flot");
69  }
70 
77  public function setSize($a_x, $a_y)
78  {
79  $this->width = (int)$a_x;
80  $this->height = (int)$a_y;
81  }
82 
90  public function addData(ilChartData $a_series, $a_idx = null)
91  {
92  if($a_idx === null)
93  {
94  $a_idx = sizeof($this->data);
95  }
96  $this->data[$a_idx] = $a_series;
97  return $a_idx;
98  }
99 
105  public function setLegend(ilChartLegend $a_legend)
106  {
107  $this->legend = $a_legend;
108  }
109 
116  public static function isValidColor($a_value)
117  {
118  if(preg_match("/^#[0-9a-f]{3}$/i", $a_value, $match))
119  {
120  return true;
121  }
122  else if(preg_match("/^#[0-9a-f]{6}$/i", $a_value, $match))
123  {
124  return true;
125  }
126  }
127 
135  protected static function renderColor($a_value, $a_opacity = 1)
136  {
137  if(self::isValidColor($a_value))
138  {
139  if(strlen($a_value) == 4)
140  {
141  return "\"rgba(".hexdec($a_value[1].$a_value[1]).", ".
142  hexdec($a_value[2].$a_value[2]).", ".
143  hexdec($a_value[3].$a_value[3]).", ".$a_opacity.")\"";
144  }
145  else
146  {
147  return "\"rgba(".hexdec($a_value[1].$a_value[2]).", ".
148  hexdec($a_value[3].$a_value[4]).", ".
149  hexdec($a_value[5].$a_value[6]).", ".$a_opacity.")\"";
150  }
151  }
152  }
153 
159  public function setShadow($a_value)
160  {
161  $this->shadow = (int)$a_value;
162  }
163 
169  public function getShadow()
170  {
171  return $this->shadow;
172  }
173 
179  public function setColors($a_values)
180  {
181  foreach($a_values as $color)
182  {
183  if(self::isValidColor($color))
184  {
185  $this->colors[] = $color;
186  }
187  }
188  }
189 
195  public function getColors()
196  {
197  return $this->colors;
198  }
199 
207  public function setTicks($a_x, $a_y, $a_labeled = false)
208  {
209  $this->ticks = array("x" => $a_x, "y" => $a_y, "labeled" => (bool)$a_labeled);
210  }
211 
217  public function getTicks()
218  {
219  return $this->ticks;
220  }
221 
227  function setLegLabels($a_val)
228  {
229  $this->leg_labels = $a_val;
230  }
231 
237  function getLegLabels()
238  {
239  return $this->leg_labels;
240  }
241 
245  public function getHTML()
246  {
247  global $tpl;
248 
249  include_once "Services/jQuery/classes/class.iljQueryUtil.php";
251 
252  $tpl->addJavascript("Services/Chart/js/flot/excanvas.min.js");
253  $tpl->addJavascript("Services/Chart/js/flot/jquery.flot.min.js");
254  $tpl->addJavascript("Services/Chart/js/flot/jquery.flot.pie.js");
255  $tpl->addJavascript("Services/Chart/js/flot/jquery.flot.highlighter.js");
256  $tpl->addJavascript("Services/Chart/js/flot/jquery.flot.spider.js");
257 
258  $chart = new ilTemplate("tpl.grid.html", true, true, "Services/Chart");
259  $chart->setVariable("ID", $this->id);
260  $chart->setVariable("WIDTH", $this->width);
261  $chart->setVariable("HEIGHT", $this->height);
262 
263  $last = array_keys($this->data);
264  $last = array_pop($last);
265  $has_pie = false;
266  $has_spider = false;
267  foreach($this->data as $idx => $series)
268  {
269  $fill = $series->getFill();
270 
271  if ($series->getType() == "spider")
272  {
273  $has_spider = true;
274 
275  if ($fill["color"] != "")
276  {
277  $chart->setCurrentBlock("series_property");
278  $chart->setVariable("SPROP", "color");
279  $chart->setVariable("SPROP_VAL", self::renderColor($fill["color"] , "0.5"));
280  $chart->parseCurrentBlock();
281  }
282  }
283 
284  $chart->setCurrentBlock("series");
285  $chart->setVariable("SERIES_LABEL", str_replace("\"", "\\\"", $series->getLabel()));
286  $chart->setVariable("SERIES_TYPE", $series->getType());
287 
288  $type = $series->getType();
289 
290  $points = array();
291  if($type != "pie")
292  {
293  foreach($series->getData() as $point)
294  {
295  $points[] = "[".$point[0].",".$point[1]."]";
296  }
297  $chart->setVariable("SERIES_DATA", "[ ".implode(",", $points)." ]");
298  }
299  else
300  {
301  $has_pie = true;
302  $chart->setVariable("SERIES_DATA", array_pop($series->getData()));
303  }
304  if($idx != $last)
305  {
306  $chart->setVariable("SERIES_END", ",");
307  }
308 
309  $options = array("show: ".($series->isHidden() ? "false" : "true"));
310  if($type != "points")
311  {
312  $width = $series->getLineWidth();
313  if($width !== null)
314  {
315  $options[] = "lineWidth:".$width;
316  }
317  if($type == "bars")
318  {
319  $bar_options = $series->getBarOptions();
320  if($bar_options["width"] !== null)
321  {
322  $options[] = "barWidth:".str_replace(",", ".", $bar_options["width"]);
323  $options[] = "align: \"".$bar_options["align"]."\"";
324  if($bar_options["horizontal"])
325  {
326  $options[] = "horizontal: true";
327  }
328  }
329  }
330  else if($type == "lines")
331  {
332  if($series->getLineSteps())
333  {
334  $options[] = "steps: true";
335  }
336  }
337  }
338  else
339  {
340  $radius = $series->getPointRadius();
341  if($radius !== null)
342  {
343  $options[] = "radius:".$radius;
344  }
345  }
346 
347  if($fill["fill"])
348  {
349  $options[] = "fill: ".$fill["fill"];
350  if($fill["color"])
351  {
352  $options[] = "fillColor: ".self::renderColor($fill["color"], $fill["fill"]);
353  }
354  }
355  $chart->setVariable("SERIES_OPTIONS", implode(", ", $options));
356 
357  $chart->parseCurrentBlock();
358  }
359 
360  if ($has_spider)
361  {
362  $chart->setCurrentBlock("spider");
363  $lab_strings = array();
364  $max_str_len = 0;
365  foreach ($this->getLegLabels() as $l)
366  {
367  $l = ilUtil::shortenText ($l, 80, true);
368  $lab_strings[] = "{label: \"".$l."\"}";
369  $max_str_len = max($max_str_len, strlen($l));
370  }
371  $chart->setVariable("LEG_LABELS", implode($lab_strings, ","));
372  $chart->setVariable("LEG_MAX", $this->getYAxisMax());
373  switch (count($this->getLegLabels()))
374  {
375  case 4:
376  case 6:
377  $chart->setVariable("LEG_START_ANGLE", "10");
378  break;
379 
380  default:
381  $chart->setVariable("LEG_START_ANGLE", "0");
382  break;
383  }
384  if ($max_str_len > 60)
385  {
386  $chart->setVariable("FONT_SIZE", "10");
387  }
388  else if ($max_str_len > 30)
389  {
390  $chart->setVariable("FONT_SIZE", "12");
391  }
392  else
393  {
394  $chart->setVariable("FONT_SIZE", "15");
395  }
396  $chart->parseCurrentBlock();
397 
398  $chart->setCurrentBlock("spider_grid_options");
399  $chart->setVariable("NR_TICKS", $this->getYAxisMax());
400  $chart->parseCurrentBlock();
401  }
402 
403  // global options
404 
405  $chart->setVariable("SHADOW", (int)$this->getShadow());
406  $chart->setVariable("IS_PIE", ($has_pie ? "true" : "false"));
407 
408  $colors = $this->getColors();
409  if($colors)
410  {
411  $tmp = array();
412  foreach($colors as $color)
413  {
414  $tmp[] = self::renderColor($color);
415  }
416  }
417  if(sizeof($tmp))
418  {
419  $chart->setVariable("COLORS", implode(",", $tmp));
420  }
421 
422  // legend
423  if(!$this->legend)
424  {
425  $chart->setVariable("LEGEND", "show: false");
426  }
427  else
428  {
429  $margin = $this->legend->getMargin();
430  $legend = array();
431  $legend[] = "show: true";
432  $legend[] = "noColumns: ".$this->legend->getColumns();
433  $legend[] = "position: \"".$this->legend->getPosition()."\"";
434  $legend[] = "margin: [".$margin["x"].", ".$margin["y"]."]";
435  $legend[] = "backgroundColor: ".self::renderColor($this->legend->getBackground());
436  $legend[] = "backgroundOpacity: ".str_replace(",",".",$this->legend->getOpacity());
437  $legend[] = "labelBoxBorderColor: ".self::renderColor($this->legend->getLabelBorder());
438 
439  $chart->setVariable("LEGEND", implode(", ", $legend));
440  }
441 
442  // axis/ticks
443  $tmp = array();
444  $ticks = $this->getTicks();
445  if($ticks)
446  {
447  foreach($ticks as $axis => $def)
448  {
449  if(is_numeric($def))
450  {
451  $tmp[$axis] = $axis."axis: { ticks: ".$def." }";
452  }
453  else if(is_array($def))
454  {
455  $ttmp = array();
456  foreach($def as $idx => $value)
457  {
458  if($ticks["labeled"])
459  {
460  $ttmp[] = "[".$idx.", \"".$value."\"]";
461  }
462  else
463  {
464  $ttmp[] = $value;
465  }
466  }
467  $tmp[$axis] = $axis."axis: { ticks: [".implode(", ", $ttmp)."] }";
468  }
469  }
470  }
471 
472  // optional: remove decimals
473  if(!isset($tmp["x"]) && $this->integer_axis["x"])
474  {
475  $tmp["x"] = "xaxis: { tickDecimals: 0 }";
476  }
477  if(!isset($tmp["y"]) && $this->integer_axis["y"])
478  {
479  $tmp["y"] = "yaxis: { tickDecimals: 0 }";
480  }
481 
482  if(sizeof($tmp))
483  {
484  $chart->setVariable("AXIS", ",".implode(", ", $tmp));
485  }
486 
487  $ret = $chart->get();
488 //echo htmlentities($ret);
489  return $ret;
490  }
491 
492  function setYAxisToInteger($a_status)
493  {
494  $this->integer_axis["y"] = (bool)$a_status;
495  }
496 
497  function setXAxisToInteger($a_status)
498  {
499  $this->integer_axis["x"] = (bool)$a_status;
500  }
501 
507  function setYAxisMax($a_val)
508  {
509  $this->y_max = $a_val;
510  }
511 
517  function getYAxisMax()
518  {
519  return $this->y_max;
520  }
521 
522  /*
523  ilChart
524  ->setColors
525  ->setHover() [tooltip?]
526  [->setClick]
527  ->setZooming
528  ->setPanning
529  ->setTooltip
530  ->addData[Series]
531  - labels
532  - type
533  - pie: nur 1x
534  - bar, lines, points, steps, stacked?
535  - highlight?!
536  => min/max, transmission type (google api)
537 
538 
539  grid-based
540  ->setGrid
541  ->setTicks(color, size, decimals, length)
542  ->addAxisX (multiple, Zero) [id, mode, position, color, label]
543  ->addAxisY (multiple?) [id, mode, position, color, label]
544  ->setBackgroundFill(opacity, color/gradient)
545  ->setThreshold(int/float)
546  ->setToggles(bool)
547 
548  pie
549  ->setCollapse(int/float, color, label)
550  ->setRotation(int angle?)
551  ->setRadius(inner, outer)
552  */
553 }
554 
555 ?>