3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2015
34 require_once 'packages/OpenFlashChart/php-ofc-library/open-flash-chart.php';
37 * Build various graphs using Open Flash Chart library.
39 class CRM_Utils_OpenFlashChart
{
45 private static $_colours = array(
61 * Build The Bar Gharph.
63 * @param array $params
64 * Assoc array of name/value pairs.
67 * $chart object of open flash chart.
69 public static function &barChart(&$params) {
74 if (empty($params['multiValues'])) {
75 $params['multiValues'] = array($params['values']);
78 $values = CRM_Utils_Array
::value('multiValues', $params);
79 if (!is_array($values) ||
empty($values)) {
83 // get the required data.
84 $chartTitle = !empty($params['legend']) ?
$params['legend'] : ts('Bar Chart');
86 $xValues = $yValues = array();
87 $xValues = array_keys($values[0]);
88 $yValues = array_values($values[0]);
90 // set y axis parameters.
93 // calculate max scale for graph.
94 $yMax = ceil(max($yValues));
95 if ($mod = $yMax %
(str_pad(5, strlen($yMax) - 1, 0))) {
96 $yMax +
= str_pad(5, strlen($yMax) - 1, 0) - $mod;
101 $config = CRM_Core_Config
::singleton();
102 $symbol = $config->defaultCurrencySymbol
;
103 foreach ($values as $barCount => $barVal) {
104 $bars[$barCount] = new bar_glass();
106 $yValues = array_values($barVal);
107 foreach ($yValues as &$yVal) {
108 // type casting is required for chart to render values correctly
109 $yVal = (double) $yVal;
111 $bars[$barCount]->set_values($yValues);
113 // FIXME: for bars > 2, we'll need to come out with other colors
114 $bars[$barCount]->colour('#BF3B69');
117 if ($barKey = CRM_Utils_Array
::value($barCount, CRM_Utils_Array
::value('barKeys', $params))) {
118 $bars[$barCount]->key($barKey, 12);
121 // call user define function to handle on click event.
122 if ($onClickFunName = CRM_Utils_Array
::value('on_click_fun_name', $params)) {
123 $bars[$barCount]->set_on_click($onClickFunName);
126 // get the currency to set in tooltip.
127 $tooltip = CRM_Utils_Array
::value('tip', $params, "$symbol #val#");
128 $bars[$barCount]->set_tooltip($tooltip);
131 // create x axis label obj.
132 $xLabels = new x_axis_labels();
133 // set_labels function requires xValues array of string or x_axis_label
134 // so type casting array values to string values
135 array_walk($xValues, function (&$value, $index) {
136 $value = (string) $value;
138 $xLabels->set_labels($xValues);
140 // set angle for labels.
141 if ($xLabelAngle = CRM_Utils_Array
::value('xLabelAngle', $params)) {
142 $xLabels->rotate($xLabelAngle);
145 // create x axis obj.
146 $xAxis = new x_axis();
147 $xAxis->set_labels($xLabels);
149 // create y axis and set range.
150 $yAxis = new y_axis();
151 $yAxis->set_range($yMin, $yMax, $ySteps);
153 // create chart title obj.
154 $title = new title($chartTitle);
157 $chart = new open_flash_chart();
159 // add x axis w/ labels to chart.
160 $chart->set_x_axis($xAxis);
162 // add y axis values to chart.
163 $chart->add_y_axis($yAxis);
165 // set title to chart.
166 $chart->set_title($title);
168 // add bar element to chart.
169 foreach ($bars as $bar) {
170 $chart->add_element($bar);
173 // add x axis legend.
174 if ($xName = CRM_Utils_Array
::value('xname', $params)) {
175 $xLegend = new x_legend($xName);
176 $xLegend->set_style("{font-size: 13px; color:#000000; font-family: Verdana; text-align: center;}");
177 $chart->set_x_legend($xLegend);
180 // add y axis legend.
181 if ($yName = CRM_Utils_Array
::value('yname', $params)) {
182 $yLegend = new y_legend($yName);
183 $yLegend->set_style("{font-size: 13px; color:#000000; font-family: Verdana; text-align: center;}");
184 $chart->set_y_legend($yLegend);
191 * Build The Pie Gharph.
193 * @param array $params
194 * Assoc array of name/value pairs.
197 * $chart object of open flash chart.
199 public static function &pieChart(&$params) {
201 if (empty($params)) {
204 $allValues = CRM_Utils_Array
::value('values', $params);
205 if (!is_array($allValues) ||
empty($allValues)) {
209 // get the required data.
211 foreach ($allValues as $label => $value) {
212 $values[] = new pie_value((double) $value, $label);
214 $graphTitle = !empty($params['legend']) ?
$params['legend'] : ts('Pie Chart');
217 $config = CRM_Core_Config
::singleton();
218 $symbol = $config->defaultCurrencySymbol
;
223 // call user define function to handle on click event.
224 if ($onClickFunName = CRM_Utils_Array
::value('on_click_fun_name', $params)) {
225 $pie->on_click($onClickFunName);
228 $pie->set_start_angle(35);
229 $pie->add_animation(new pie_fade());
230 $pie->add_animation(new pie_bounce(2));
233 $tooltip = CRM_Utils_Array
::value('tip', $params, "Amount is $symbol #val# of $symbol #total# <br>#percent#");
234 $pie->set_tooltip($tooltip);
237 $pie->set_colours(self
::$_colours);
239 $pie->set_values($values);
242 $chart = new open_flash_chart();
244 // create chart title obj.
245 $title = new title($graphTitle);
246 $chart->set_title($title);
248 $chart->add_element($pie);
249 $chart->x_axis
= NULL;
255 * Build The 3-D Bar Gharph.
257 * @param array $params
258 * Assoc array of name/value pairs.
261 * $chart object of open flash chart.
263 public static function &bar_3dChart(&$params) {
265 if (empty($params)) {
269 // $params['values'] should contains the values for each
270 // criteria defined in $params['criteria']
271 $values = CRM_Utils_Array
::value('values', $params);
272 $criteria = CRM_Utils_Array
::value('criteria', $params);
273 if (!is_array($values) ||
empty($values) ||
!is_array($criteria) ||
empty($criteria)) {
277 // get the required data.
278 $xReferences = $xValueLabels = $xValues = $yValues = array();
280 foreach ($values as $xVal => $yVal) {
281 if (!is_array($yVal) ||
empty($yVal)) {
285 $xValueLabels[] = (string) $xVal;
286 foreach ($criteria as $criteria) {
287 $xReferences[$criteria][$xVal] = (double) CRM_Utils_Array
::value($criteria, $yVal, 0);
288 $yValues[] = (double) CRM_Utils_Array
::value($criteria, $yVal, 0);
292 if (empty($xReferences)) {
299 $config = CRM_Core_Config
::singleton();
300 $symbol = $config->defaultCurrencySymbol
;
303 $tooltip = CRM_Utils_Array
::value('tip', $params, "$symbol #val#");
306 foreach ($xReferences as $criteria => $values) {
307 $toolTipVal = $tooltip;
308 // for separate tooltip for each criteria
309 if (is_array($tooltip)) {
310 $toolTipVal = CRM_Utils_Array
::value($criteria, $tooltip, "$symbol #val#");
313 // create bar_3d object
314 $xValues[$count] = new bar_3d();
316 $xValues[$count]->set_colour(self
::$_colours[$count]);
317 // define colur pattel with bar criteria
318 $xValues[$count]->key((string) $criteria, 12);
319 // define bar chart values
320 $xValues[$count]->set_values(array_values($values));
323 $xValues[$count]->set_tooltip($toolTipVal);
327 $chartTitle = !empty($params['legend']) ?
$params['legend'] : ts('Bar Chart');
329 // set y axis parameters.
332 // calculate max scale for graph.
333 $yMax = ceil(max($yValues));
334 if ($mod = $yMax %
(str_pad(5, strlen($yMax) - 1, 0))) {
335 $yMax +
= str_pad(5, strlen($yMax) - 1, 0) - $mod;
338 // if max value of y-axis <= 0, then set default values
347 // create x axis label obj.
348 $xLabels = new x_axis_labels();
349 $xLabels->set_labels($xValueLabels);
351 // set angle for labels.
352 if ($xLabelAngle = CRM_Utils_Array
::value('xLabelAngle', $params)) {
353 $xLabels->rotate($xLabelAngle);
356 // create x axis obj.
357 $xAxis = new x_axis();
358 $xAxis->set_labels($xLabels);
360 // create y axis and set range.
361 $yAxis = new y_axis();
362 $yAxis->set_range($yMin, $yMax, $ySteps);
364 // create chart title obj.
365 $title = new title($chartTitle);
368 $chart = new open_flash_chart();
370 // add x axis w/ labels to chart.
371 $chart->set_x_axis($xAxis);
373 // add y axis values to chart.
374 $chart->add_y_axis($yAxis);
376 // set title to chart.
377 $chart->set_title($title);
379 foreach ($xValues as $bar) {
380 // add bar element to chart.
381 $chart->add_element($bar);
384 // add x axis legend.
385 if ($xName = CRM_Utils_Array
::value('xname', $params)) {
386 $xLegend = new x_legend($xName);
387 $xLegend->set_style("{font-size: 13px; color:#000000; font-family: Verdana; text-align: center;}");
388 $chart->set_x_legend($xLegend);
391 // add y axis legend.
392 if ($yName = CRM_Utils_Array
::value('yname', $params)) {
393 $yLegend = new y_legend($yName);
394 $yLegend->set_style("{font-size: 13px; color:#000000; font-family: Verdana; text-align: center;}");
395 $chart->set_y_legend($yLegend);
408 public static function chart($rows, $chart, $interval) {
409 $chartData = $dateKeys = array();
413 foreach ($rows['receive_date'] as $key => $val) {
414 list($year, $month) = explode('-', $val);
415 $dateKeys[] = substr($rows['Month'][$key], 0, 3) . ' ' . $year;
417 $legend = ts('Monthly');
421 foreach ($rows['receive_date'] as $key => $val) {
422 list($year, $month) = explode('-', $val);
423 $dateKeys[] = 'Quarter ' . $rows['Quarter'][$key] . ' of ' . $year;
425 $legend = ts('Quarterly');
429 foreach ($rows['receive_date'] as $key => $val) {
430 list($year, $month) = explode('-', $val);
431 $dateKeys[] = 'Week ' . $rows['Week'][$key] . ' of ' . $year;
433 $legend = ts('Weekly');
437 foreach ($rows['receive_date'] as $key => $val) {
438 list($year, $month) = explode('-', $val);
441 $legend = ts('Yearly');
445 if (!empty($dateKeys)) {
447 if (!array_key_exists('multiValue', $rows)) {
448 $rows['multiValue'] = array($rows['value']);
450 foreach ($rows['multiValue'] as $key => $val) {
451 $graph[$key] = array_combine($dateKeys, $rows['multiValue'][$key]);
454 'legend' => "$legend " . CRM_Utils_Array
::value('legend', $rows, ts('Contribution')) . ' ' . ts('Summary'),
455 'values' => $graph[0],
456 'multiValues' => $graph,
457 'barKeys' => CRM_Utils_Array
::value('barKeys', $rows, array()),
461 // rotate the x labels.
462 $chartData['xLabelAngle'] = CRM_Utils_Array
::value('xLabelAngle', $rows, 0);
463 if (!empty($rows['tip'])) {
464 $chartData['tip'] = $rows['tip'];
468 $chartData['xname'] = CRM_Utils_Array
::value('xname', $rows);
469 $chartData['yname'] = CRM_Utils_Array
::value('yname', $rows);
471 // carry some chart params if pass.
477 if (!empty($rows[$f])) {
478 $chartData[$f] = $rows[$f];
482 return self
::buildChart($chartData, $chart);
493 public static function reportChart($rows, $chart, $interval, &$chartInfo) {
494 foreach ($interval as $key => $val) {
495 $graph[$val] = $rows['value'][$key];
500 'legend' => $chartInfo['legend'],
501 'xname' => $chartInfo['xname'],
502 'yname' => $chartInfo['yname'],
505 // rotate the x labels.
506 $chartData['xLabelAngle'] = CRM_Utils_Array
::value('xLabelAngle', $chartInfo, 20);
507 if (!empty($chartInfo['tip'])) {
508 $chartData['tip'] = $chartInfo['tip'];
511 // carry some chart params if pass.
517 if (!empty($rows[$f])) {
518 $chartData[$f] = $rows[$f];
522 return self
::buildChart($chartData, $chart);
526 * @param array $params
531 public static function buildChart(&$params, $chart) {
532 $openFlashChart = array();
533 if ($chart && is_array($params) && !empty($params)) {
534 // build the chart objects.
535 $chartObj = CRM_Utils_OpenFlashChart
::$chart($params);
537 $openFlashChart = array();
539 // calculate chart size.
540 $xSize = CRM_Utils_Array
::value('xSize', $params, 400);
541 $ySize = CRM_Utils_Array
::value('ySize', $params, 300);
542 if ($chart == 'barChart') {
543 $ySize = CRM_Utils_Array
::value('ySize', $params, 250);
544 $xSize = 60 * count($params['values']);
545 // hack to show tooltip.
547 $xSize = (count($params['values']) > 1) ?
100 * count($params['values']) : 170;
549 elseif ($xSize > 600 && count($params['values']) > 1) {
550 $xSize = (count($params['values']) +
400 / count($params['values'])) * count($params['values']);
554 // generate unique id for this chart instance
555 $uniqueId = md5(uniqid(rand(), TRUE));
557 $openFlashChart["chart_{$uniqueId}"]['size'] = array('xSize' => $xSize, 'ySize' => $ySize);
558 $openFlashChart["chart_{$uniqueId}"]['object'] = $chartObj;
560 // assign chart data to template
561 $template = CRM_Core_Smarty
::singleton();
562 $template->assign('uniqueId', $uniqueId);
563 $template->assign("openFlashChartData", json_encode($openFlashChart));
567 return $openFlashChart;