PageRenderTime 69ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/include/ChartUtils.php

https://bitbucket.org/yousef_fadila/vtiger
PHP | 523 lines | 443 code | 46 blank | 34 comment | 114 complexity | 5ccc5c2ef6530765f98513e63634a6b8 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. <?php
  2. /*+**********************************************************************************
  3. * The contents of this file are subject to the vtiger CRM Public License Version 1.0
  4. * ("License"); You may not use this file except in compliance with the License
  5. * The Original Code is: vtiger CRM Open Source
  6. * The Initial Developer of the Original Code is vtiger.
  7. * Portions created by vtiger are Copyright (C) vtiger.
  8. * All Rights Reserved.
  9. ************************************************************************************/
  10. require_once('include/utils/utils.php');
  11. require_once 'include/utils/CommonUtils.php';
  12. Class ChartUtils {
  13. // Function to generate Bar Chart
  14. public static function getBarChart($xaxisData, $yaxisData, $title='', $width='', $height='', $charttype='vertical', $cachedFileName=false, $target=false, $color='') {
  15. global $log, $lang_crm, $default_charset;
  16. require_once('include/utils/utils.php');
  17. require_once('include/utils/GraphUtils.php');
  18. include_once ('Image/Graph.php');
  19. include_once ('Image/Canvas.php');
  20. $barwidth = '70';
  21. if ($cachedFileName === false) {
  22. $cache_file_name = 'cache/images/bar_chart_' . time() . '.png';
  23. } else {
  24. $cache_file_name = $cachedFileName;
  25. }
  26. if (empty($width))
  27. $width = '400';
  28. if (empty($height))
  29. $height = '300';
  30. if ($target === false)
  31. $target = array();
  32. if (empty($color))
  33. $color = 'black';
  34. $alts = array();
  35. $temp = array();
  36. for ($i = 0; $i < count($xaxisData); $i++) {
  37. $name = html_entity_decode($xaxisData[$i], ENT_QUOTES, $default_charset);
  38. $pos = substr_count($name, " ");
  39. $alts[] = $name;
  40. //If the daatx value of a string is greater, adding '\n' to it so that it'll cme inh 2nd line
  41. if (strlen($name) >= 14)
  42. $name = substr($name, 0, 44);
  43. if ($pos >= 2) {
  44. $val = explode(" ", $name);
  45. $n = count($val) - 1;
  46. $x = "";
  47. for ($j = 0; $j < count($val); $j++) {
  48. if ($j != $n) {
  49. $x .=" " . $val[$j];
  50. } else {
  51. $x .= "@#" . $val[$j];
  52. }
  53. }
  54. $name = $x;
  55. }
  56. $name = str_replace("@#", " ", $name);
  57. $temp[] = html_entity_decode($name, ENT_QUOTES, $default_charset);
  58. }
  59. $xaxisData = $temp;
  60. // Set the basic parameters of the graph
  61. $canvas = & Image_Canvas::factory('png', array('width' => $width, 'height' => $height, 'usemap' => true));
  62. $imagemap = $canvas->getImageMap();
  63. $graph = & Image_Graph::factory('graph', $canvas);
  64. $font = & $graph->addNew('font', calculate_font_name($lang_crm));
  65. $font->setSize(8);
  66. $font_color = "#000000";
  67. $font->setColor($font_color);
  68. $graph->setFont($font);
  69. $titlestr = & Image_Graph::factory('title', array($title, 8));
  70. $plotarea = & Image_Graph::factory('plotarea', array(
  71. 'axis',
  72. 'axis',
  73. $charttype
  74. ));
  75. $graph->add(Image_Graph::vertical($titlestr, $plotarea, 5));
  76. // Now create a bar plot
  77. $max = 0;
  78. // To create unique lables we need to keep track of lable name and its count
  79. $uniquex = array();
  80. $xlabels = array();
  81. $dataset = & Image_Graph::factory('dataset');
  82. if ($charttype == 'horizontal') {
  83. $fill = & Image_Graph::factory('gradient', array(IMAGE_GRAPH_GRAD_VERTICAL_MIRRORED, $color, 'white'));
  84. } else {
  85. $fill = & Image_Graph::factory('gradient', array(IMAGE_GRAPH_GRAD_HORIZONTAL_MIRRORED, $color, 'white'));
  86. }
  87. for ($i = 0; $i < count($yaxisData); $i++) {
  88. $x = 1 + $i;
  89. if ($yaxisData[$i] >= $max)
  90. $max = $yaxisData[$i];
  91. $dataset->addPoint(
  92. $x,
  93. $yaxisData[$i],
  94. array(
  95. 'url' => $target[$i],
  96. 'alt' => $alts[$i] . '=' . $yaxisData[$i]
  97. )
  98. );
  99. $xlabels[$x] = $xaxisData[$i];
  100. // To have unique names even in case of duplicates let us add the id
  101. $xaxisData_appearance = $uniquex[$xaxisData[$i]];
  102. if ($xaxisData_appearance == null) {
  103. $uniquex[$xaxisData[$i]] = 1;
  104. } else {
  105. $xlabels[$x] = $xaxisData[$i] . ' [' . $xaxisData_appearance . ']';
  106. $uniquex[$xaxisData[$i]] = $xaxisData_appearance + 1;
  107. }
  108. }
  109. $bplot = & $plotarea->addNew('bar', $dataset);
  110. $bplot->setFillStyle($fill);
  111. //You can change the width of the bars if you like
  112. if (!empty($xaxisData))
  113. $bplot->setBarWidth($barwidth / count($xaxisData), "%");
  114. //$bplot->setPadding(array('top'=>10));
  115. $bplot->setBackground(Image_Graph::factory('gradient', array(IMAGE_GRAPH_GRAD_HORIZONTAL, 'white', 'white')));
  116. $xaxis = & $plotarea->getAxis(IMAGE_GRAPH_AXIS_X);
  117. $yaxis = & $plotarea->getAxis(IMAGE_GRAPH_AXIS_Y);
  118. $yaxis->setFontSize(8);
  119. $xaxis->setFontSize(8);
  120. if ($charttype == 'horizontal') { // Invert X-axis and put Y-axis at bottom
  121. $xaxis->setInverted(false);
  122. $yaxis->setAxisIntersection('max');
  123. }
  124. // set grid
  125. $gridY = & $plotarea->addNew('line_grid', IMAGE_GRAPH_AXIS_Y);
  126. $gridY->setLineColor('#FFFFFF@0.5');
  127. $gridY2 = & $plotarea->addNew('bar_grid', null, IMAGE_GRAPH_AXIS_Y);
  128. $gridY2->setFillColor('#FFFFFF@0.2');
  129. // Add some grace to y-axis so the bars doesn't go all the way to the end of the plot area
  130. $yaxis->forceMaximum(round(($max * 1.1) + 0.5));
  131. $ticks = get_tickspacing(round(($max * 1.1) + 0.5));
  132. // First make the labels look right
  133. if ($charttype == 'horizontal')
  134. $yaxis->setFontAngle('vertical');
  135. $yaxis->setLabelInterval($ticks[0]);
  136. $yaxis->setTickOptions(-5, 0);
  137. $yaxis->setLabelInterval($ticks[1], 2);
  138. $yaxis->setTickOptions(-2, 0, 2);
  139. // Create the xaxis labels
  140. $array_data = & Image_Graph::factory('Image_Graph_DataPreprocessor_Array',
  141. array($xlabels)
  142. );
  143. // The fix the tick marks
  144. $xaxis->setDataPreprocessor($array_data);
  145. $xaxis->forceMinimum(0.5);
  146. $xaxis->forceMaximum(0.5 + count($yaxisData));
  147. if ($charttype == 'vertical')
  148. $xaxis->setFontAngle('vertical');
  149. $xaxis->setLabelInterval(1);
  150. $xaxis->setTickOptions(0, 0);
  151. $xaxis->setLabelInterval(2, 2);
  152. // set markers
  153. if ($width > 400 && $height > 400) {
  154. $marker = & $graph->addNew('value_marker', IMAGE_GRAPH_VALUE_Y);
  155. $marker->setFillColor('000000@0.0');
  156. $marker->setBorderColor('000000@0.0');
  157. $marker->setFontSize(8);
  158. // shift markers 20 pix right
  159. if ($charttype == 'horizontal') {
  160. $marker_pointing = & $graph->addNew('Image_Graph_Marker_Pointing', array(10, 0, & $marker));
  161. } else {
  162. $marker_pointing = & $graph->addNew('Image_Graph_Marker_Pointing', array(0, -10, & $marker));
  163. }
  164. $marker_pointing->setLineColor('000000@0.0');
  165. $bplot->setMarker($marker_pointing);
  166. }
  167. //Getting the graph in the form of html page
  168. $img = $graph->done(
  169. array(
  170. 'tohtml' => true,
  171. 'border' => 0,
  172. 'filename' => $cache_file_name,
  173. 'filepath' => '',
  174. 'urlpath' => ''
  175. ));
  176. return $img;
  177. }
  178. // Function to generate Pie Chart
  179. public static function getPieChart($xaxisData, $yaxisData, $title='', $width='', $height='', $charttype='vertical', $cachedFileName=false, $target=false, $color='') {
  180. global $log, $lang_crm, $default_charset;
  181. require_once('include/utils/utils.php');
  182. require_once('include/utils/GraphUtils.php');
  183. include_once ('Image/Graph.php');
  184. include_once ('Image/Canvas.php');
  185. if ($cachedFileName === false) {
  186. $cache_file_name = 'cache/images/pie_chart_' . time() . '.png';
  187. } else {
  188. $cache_file_name = $cachedFileName;
  189. }
  190. if (empty($width))
  191. $width = '500';
  192. if (empty($height))
  193. $height = '400';
  194. if ($target === false)
  195. $target = array();
  196. $alts = array();
  197. $temp = array();
  198. for ($i = 0; $i < count($xaxisData); $i++) {
  199. $name = html_entity_decode($xaxisData[$i], ENT_QUOTES, $default_charset);
  200. $pos = substr_count($name, " ");
  201. $alts[] = $name;
  202. //If the datax value of a string is greater, adding '\n' to it so that it'll come in 2nd line
  203. if (strlen($name) >= 14)
  204. $name = substr($name, 0, 34);
  205. if ($pos >= 2) {
  206. $val = explode(" ", $name);
  207. $n = count($val) - 1;
  208. $x = "";
  209. for ($j = 0; $j < count($val); $j++) {
  210. if ($j != $n) {
  211. $x .=" " . $val[$j];
  212. } else {
  213. $x .= "@#" . $val[$j];
  214. }
  215. }
  216. $name = $x;
  217. }
  218. $name = str_replace("@#", "\n", $name);
  219. $temp[] = $name;
  220. }
  221. $xaxisData = $temp;
  222. $width = $width + ($width / 5);
  223. $canvas = & Image_Canvas::factory('png', array('width' => $width, 'height' => $height, 'usemap' => true));
  224. $imagemap = $canvas->getImageMap();
  225. $graph = & Image_Graph::factory('graph', $canvas);
  226. $font = & $graph->addNew('font', calculate_font_name($lang_crm));
  227. $font->setSize(8);
  228. $font->setColor($color);
  229. $graph->setFont($font);
  230. // create the plotarea layout
  231. $title = & Image_Graph::factory('title', array($title, 10));
  232. $plotarea = & Image_Graph::factory('plotarea', array(
  233. 'category',
  234. 'axis'
  235. ));
  236. $graph->add(Image_Graph::vertical($title, $plotarea, 5));
  237. // To create unique lables we need to keep track of lable name and its count
  238. $uniquex = array();
  239. // Generate colours
  240. $colors = color_generator(count($yaxisData), '#33DDFF', '#3322FF');
  241. $dataset = & Image_Graph::factory('dataset');
  242. $fills = & Image_Graph::factory('Image_Graph_Fill_Array');
  243. $sum = 0;
  244. $pcvalues = array();
  245. for ($i = 0; $i < count($yaxisData); $i++) {
  246. $sum += $yaxisData[$i];
  247. }
  248. for ($i = 0; $i < count($yaxisData); $i++) {
  249. // To have unique names even in case of duplicates let us add the id
  250. $datalabel = $xaxisData[$i];
  251. $xaxisData_appearance = $uniquex[$xaxisData[$i]];
  252. if ($xaxisData_appearance == null) {
  253. $uniquex[$xaxisData[$i]] = 1;
  254. } else {
  255. $datalabel = $xaxisData[$i] . ' [' . $xaxisData_appearance . ']';
  256. $uniquex[$xaxisData[$i]] = $xaxisData_appearance + 1;
  257. }
  258. $dataset->addPoint(
  259. $datalabel,
  260. $yaxisData[$i],
  261. array(
  262. 'url' => $target[$i],
  263. 'alt' => $alts[$i] . '=' . sprintf('%0.1f%%', 100 * $yaxisData[$i] / $sum)
  264. )
  265. );
  266. $pcvalues[$yaxisData[$i]] = sprintf('%0.1f%%', 100 * $yaxisData[$i] / $sum);
  267. $fills->addColor($colors[$i]);
  268. }
  269. if ($sum == 0)
  270. return null;
  271. // create the pie chart and associate the filling colours
  272. $gbplot = & $plotarea->addNew('pie', $dataset);
  273. $plotarea->setPadding(array('top' => 0, 'bottom' => 0, 'left' => 0, 'right' => ($width / 20)));
  274. $plotarea->hideAxis();
  275. $gbplot->setFillStyle($fills);
  276. // format the data values
  277. $marker_array = & Image_Graph::factory('Image_Graph_DataPreprocessor_Array', array($pcvalues));
  278. // set markers
  279. $marker = & $graph->addNew('value_marker', IMAGE_GRAPH_VALUE_Y);
  280. $marker->setDataPreprocessor($marker_array);
  281. $marker->setFillColor('#FFFFFF');
  282. $marker->setBorderColor($color);
  283. $marker->setFontColor($color);
  284. $marker->setFontSize(8);
  285. $pointingMarker = & $graph->addNew('Image_Graph_Marker_Pointing_Angular', array(20, &$marker));
  286. $gbplot->setMarker($pointingMarker);
  287. $legend_box = & $plotarea->addNew('legend');
  288. $legend_box->setPadding(array('top' => 20, 'bottom' => 0, 'left' => 0, 'right' => 0));
  289. $legend_box->setFillColor('#F5F5F5');
  290. $legend_box->showShadow();
  291. $img = $graph->done(array(
  292. 'tohtml' => true,
  293. 'border' => 0,
  294. 'filename' => $cache_file_name,
  295. 'filepath' => '',
  296. 'urlpath' => ''
  297. ));
  298. return $img;
  299. }
  300. //Generates Chart Data in form of an array from the Query Result of reports
  301. public static function generateChartDataFromReports($queryResult, $groupbyField, $fieldDetails='', $reportid='') {
  302. require_once 'modules/Reports/CustomReportUtils.php';
  303. require_once('include/Webservices/Utils.php');
  304. require_once('include/Webservices/Query.php');
  305. global $adb, $current_user, $theme, $default_charset;
  306. $inventorymodules = array('Quotes', 'SalesOrder', 'PurchaseOrder', 'Invoice', 'Products', 'PriceBooks', 'Vendors', 'Services');
  307. $rows = $adb->num_rows($queryResult);
  308. $condition = "is";
  309. $current_theme = $theme;
  310. $groupByFields = array();
  311. $yaxisArray = array();
  312. $ChartDataArray = array();
  313. $target_val = array();
  314. $report = new ReportRun($reportid);
  315. $restrictedModules = array();
  316. if($report->secondarymodule!='') {
  317. $reportModules = explode(":",$report->secondarymodule);
  318. } else {
  319. $reportModules = array();
  320. }
  321. array_push($reportModules,$report->primarymodule);
  322. $restrictedModules = false;
  323. foreach($reportModules as $mod) {
  324. if(isPermitted($mod,'index') != "yes" || vtlib_isModuleActive($mod) == false) {
  325. if(!is_array($restrictedModules)) $restrictedModules = array();
  326. $restrictedModules[] = $mod;
  327. }
  328. }
  329. if(is_array($restrictedModules) && count($restrictedModules) > 0) {
  330. $ChartDataArray['error'] = "<h4>".getTranslatedString('LBL_NO_ACCESS', 'Reports').' - '.implode(',', $restrictedModules)."</h4>";
  331. return $ChartDataArray;
  332. }
  333. if ($fieldDetails != '') {
  334. list($tablename, $colname, $module_field, $fieldname, $single) = explode(":", $fieldDetails);
  335. list($module, $field) = split("_", $module_field);
  336. $dateField = false;
  337. if ($single == 'D') {
  338. $dateField = true;
  339. $query = "SELECT * FROM vtiger_reportgroupbycolumn WHERE reportid=? ORDER BY sortid";
  340. $result = $adb->pquery($query, array($reportid));
  341. $criteria = $adb->query_result($result, 0, 'dategroupbycriteria');
  342. }
  343. }
  344. preg_match('/&amp;/', $groupbyField, $matches);
  345. if (!empty($matches)) {
  346. $groupfield = str_replace('&amp;', '&', $groupbyField);
  347. $groupbyField = $report->replaceSpecialChar($groupfield);
  348. }
  349. $handler = vtws_getModuleHandlerFromName($module, $current_user);
  350. $meta = $handler->getMeta();
  351. $meta->retrieveMeta();
  352. $referenceFields = $meta->getReferenceFieldDetails();
  353. if($rows > 0) {
  354. $resultRow = $adb->query_result_rowdata($queryResult, 0);
  355. if(!array_key_exists($groupbyField, $resultRow)) {
  356. $ChartDataArray['error'] = "<h4>".getTranslatedString('LBL_NO_PERMISSION_FIELD', 'Dashboard')."</h4>";
  357. return $ChartDataArray;
  358. }
  359. }
  360. for ($i = 0; $i < $rows; $i++) {
  361. $groupFieldValue = $adb->query_result($queryResult, $i, strtolower($groupbyField));
  362. $decodedGroupFieldValue = html_entity_decode($groupFieldValue, ENT_QUOTES, $default_charset);
  363. if (!empty($groupFieldValue)) {
  364. if (in_array($module_field, $report->append_currency_symbol_to_value)) {
  365. $valueComp = explode('::', $groupFieldValue);
  366. $groupFieldValue = $valueComp[1];
  367. }
  368. if ($dateField) {
  369. if (!empty($groupFieldValue))
  370. $groupByFields[] = CustomReportUtils::getXAxisDateFieldValue($groupFieldValue, $criteria);
  371. else
  372. $groupByFields[] = "Null";
  373. }
  374. else if (in_array($fieldname, array_keys($referenceFields))) {
  375. if (count($referenceFields[$fieldname]) > 1) {
  376. $refenceModule = CustomReportUtils::getEntityTypeFromName($decodedGroupFieldValue, $referenceFields[$fieldname]);
  377. }
  378. else {
  379. $refenceModule = $referenceFields[$fieldname][0];
  380. }
  381. $groupByFields[] = $groupFieldValue;
  382. if ($fieldname == 'currency_id' && in_array($module, $inventorymodules)) {
  383. $tablename = 'vtiger_currency_info';
  384. } elseif ($refenceModule == 'DocumentFolders' && $fieldname == 'folderid') {
  385. $tablename = 'vtiger_attachmentsfolder';
  386. $colname = 'foldername';
  387. } else {
  388. require_once "modules/$refenceModule/$refenceModule.php";
  389. $focus = new $refenceModule();
  390. $tablename = $focus->table_name;
  391. $colname = $focus->list_link_field;
  392. $condition = "c";
  393. }
  394. } else {
  395. $groupByFields[] = $groupFieldValue;
  396. }
  397. $yaxisArray[] = $adb->query_result($queryResult, $i, 'groupby_count');
  398. if ($fieldDetails != '') {
  399. if ($dateField) {
  400. $advanceSearchCondition = CustomReportUtils::getAdvanceSearchCondition($fieldDetails, $criteria, $groupFieldValue);
  401. if ($module == 'Calendar') {
  402. $link_val = "index.php?module=" . $module . "&query=true&action=ListView&" . $advanceSearchCondition;
  403. }else
  404. $link_val = "index.php?module=" . $module . "&query=true&action=index&" . $advanceSearchCondition;
  405. }
  406. else {
  407. $cvid = getCvIdOfAll($module);
  408. $esc_search_str = urlencode($decodedGroupFieldValue);
  409. if ($single == 'DT') {
  410. $esc_search_str = urlencode($groupFieldValue);
  411. if (strtolower($fieldname) == 'modifiedtime' || strtolower($fieldname) == 'createdtime') {
  412. $tablename = 'vtiger_crmentity';
  413. $colname = $fieldname;
  414. }
  415. }
  416. if ($fieldname == 'assigned_user_id') {
  417. $tablename = 'vtiger_crmentity';
  418. $colname = 'smownerid';
  419. }
  420. if ($module == 'Calendar') {
  421. $link_val = "index.php?module=" . $module . "&action=ListView&search_text=" . $esc_search_str . "&search_field=" . $fieldname . "&searchtype=BasicSearch&query=true&operator=e&viewname=" . $cvid;
  422. } else {
  423. $link_val = "index.php?module=" . $module . "&action=index&search_text=" . $esc_search_str . "&search_field=" . $fieldname . "&searchtype=BasicSearch&query=true&operator=e&viewname=" . $cvid;
  424. }
  425. }
  426. $target_val[] = $link_val;
  427. }
  428. }
  429. }
  430. if(count($groupByFields) == 0) {
  431. $ChartDataArray['error'] = "<div class='componentName'>".getTranslatedString('LBL_NO_DATA', 'Reports')."</div";
  432. }
  433. $ChartDataArray['xaxisData'] = $groupByFields;
  434. $ChartDataArray['yaxisData'] = $yaxisArray;
  435. $ChartDataArray['targetLink'] = $target_val;
  436. $theme = $current_theme;
  437. return $ChartDataArray;
  438. }
  439. public static function getReportBarChart($queryResult, $groupbyField, $fieldDetails, $reportid, $charttype='horizontal') {
  440. global $theme;
  441. $BarChartDetails = self::generateChartDataFromReports($queryResult, $groupbyField, $fieldDetails, $reportid);
  442. $groupbyFields = $BarChartDetails['xaxisData'];
  443. $yaxisArray = $BarChartDetails['yaxisData'];
  444. $targerLinks = $BarChartDetails['targetLink'];
  445. if ($theme == "softed") {
  446. $font_color = "#212473";
  447. } else {
  448. $font_color = "#000000";
  449. }
  450. if(!empty($BarChartDetails['error'])) {
  451. return $BarChartDetails['error'];
  452. } else {
  453. $barChart = ChartUtils::getBarChart($groupbyFields, $yaxisArray, '', '350', '300', $charttype, false, $targerLinks, $font_color);
  454. return $barChart;
  455. }
  456. }
  457. public static function getReportPieChart($queryResult, $groupbyField, $fieldDetails, $reportid) {
  458. global $theme;
  459. $PieChartDetails = self::generateChartDataFromReports($queryResult, $groupbyField, $fieldDetails, $reportid);
  460. $groupbyFields = $PieChartDetails['xaxisData'];
  461. $yaxisArray = $PieChartDetails['yaxisData'];
  462. $targerLinks = $PieChartDetails['targetLink'];
  463. $charttype = 'vertical';
  464. if ($theme == "softed") {
  465. $font_color = "#212473";
  466. } else {
  467. $font_color = "#000000";
  468. }
  469. if(!empty($PieChartDetails['error'])) {
  470. return $PieChartDetails['error'];
  471. } else {
  472. $pieChart = ChartUtils::getPieChart($groupbyFields, $yaxisArray, '', '350', '300', $charttype, false, $targerLinks, $font_color);
  473. return $pieChart;
  474. }
  475. }
  476. }
  477. ?>