]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/SugarCharts/JsChart.php
Release 6.5.16
[Github/sugarcrm.git] / include / SugarCharts / JsChart.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
5  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  * 
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
16  * details.
17  * 
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  * 
23  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25  * 
26  * The interactive user interfaces in modified source and object code versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  * 
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the "Powered by
32  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33  * technical reasons, the Appropriate Legal Notices must display the words
34  * "Powered by SugarCRM".
35  ********************************************************************************/
36
37
38
39
40 require_once("include/SugarCharts/SugarChart.php");
41
42 class JsChart extends SugarChart {
43         protected $ss;
44         var $xmlFile;
45         var $jsonFilename;
46         var $chartId;
47         var $width;
48         var $height;
49         var $chartType;
50
51         function __construct() {
52                 parent::__construct();
53         }
54
55         function isSupported($chartType) {
56                 $charts = array(
57                         "stacked group by chart",
58                         "group by chart",
59                         "bar chart",
60                         "horizontal group by chart",
61                         "horizontal",
62                         "horizontal bar chart",
63                         "pie chart",
64                         "gauge chart",
65                         "funnel chart 3D",
66                         "line chart",
67                 );
68
69                 if(in_array($chartType,$charts)) {
70                         return true;
71                 } else {
72                         return false;
73                 }
74
75         }
76
77         function tab($str, $depth){
78        // $str = preg_replace('/(<\w+>)(.*)(<\/\w+>)/e', "'\\1'.htmlentities(from_html('\\2')).'\\3'", $str);
79         return str_repeat("\t", $depth) . $str . "\n";
80         }
81
82         function display($name, $xmlFile, $width='320', $height='480', $resize=false) {
83
84
85                 $this->chartId = $name;
86                 $this->height = $height;
87                 $this->width = $width;
88                 $this->xmlFile = $xmlFile;
89                 $this->chartType = $this->chart_properties['type'];
90
91                 $style = array();
92                 $chartConfig = array();
93         try {
94                     $xmlStr = $this->processXML($this->xmlFile);
95                     $json = $this->buildJson($xmlStr);
96         }
97         catch(Exception $e) {
98             $GLOBALS['log']->fatal("Unable to return chart data, invalid xml for file {$this->xmlFile}");
99             return '';
100         }
101                 $this->saveJsonFile($json);
102                 $this->ss->assign("chartId", $this->chartId);
103                 $this->ss->assign("filename", $this->jsonFilename);
104                 global $mod_strings, $app_strings;
105                 if (isset($mod_strings['LBL_REPORT_SHOW_CHART']))
106                     $this->ss->assign("showchart", $mod_strings['LBL_REPORT_SHOW_CHART']);
107
108                 $dimensions = $this->getChartDimensions($xmlStr);
109                 $this->ss->assign("width", $dimensions['width']);
110                 $this->ss->assign("height", $dimensions['height']);
111                 $config = $this->getConfigProperties();
112                 $style['gridLineColor'] = str_replace("0x","#",$config->gridLines);
113                 $style['font-family'] = $config->labelFontFamily;
114                 $style['color'] = str_replace("0x","#",$config->labelFontColor);
115                 $this->ss->assign("css", $style);
116                 foreach($this->getChartConfigParams($xmlStr) as $key => $value) {
117                         $chartConfig[$key] = $value;
118                 }
119                 $chartConfig['imageExportType'] = $this->image_export_type;
120                 $this->ss->assign("config", $chartConfig);
121                 if($json == "No Data") {
122                         $this->ss->assign("error", $app_strings['LBL_NO_DATA']);
123                 }
124
125                 if(!$this->isSupported($this->chartType)) {
126                         $this->ss->assign("error", "Unsupported Chart Type");
127                 }
128
129         }
130
131
132         function getDashletScript($id,$xmlFile="") {
133
134                 global $sugar_config, $current_user, $current_language;
135                 $this->id = $id;
136                 $this->chartId = $id;
137                 $this->xmlFile = (!$xmlFile) ? sugar_cached("xml/".$current_user->getUserPrivGuid()."_{$this->id}.xml") : $xmlFile;
138
139
140                 $style = array();
141                 $chartConfig = array();
142                 $this->ss->assign("chartId", $this->chartId);
143                 $this->ss->assign("filename", str_replace(".xml",".js",$this->xmlFile));
144                 $config = $this->getConfigProperties();
145                 $style['gridLineColor'] = str_replace("0x","#",$config->gridLines);
146                 $style['font-family'] = $config->labelFontFamily;
147                 $style['color'] = str_replace("0x","#",$config->labelFontColor);
148                 $this->ss->assign("css", $style);
149                 $xmlStr = $this->processXML($this->xmlFile);
150                 foreach($this->getChartConfigParams($xmlStr) as $key => $value) {
151                         $chartConfig[$key] = $value;
152                 }
153
154                 $chartConfig['imageExportType'] = $this->image_export_type;
155                 $this->ss->assign("config", $chartConfig);
156
157         }
158
159         function chartArray($chartsArray) {
160
161                 $customChartsArray = array();
162                 $style = array();
163                 $chartConfig = array();
164                 foreach($chartsArray as $id => $data) {
165                         $customChartsArray[$id] = array();
166                         $customChartsArray[$id]['chartId'] = $id;
167                         $customChartsArray[$id]['filename'] = str_replace(".xml",".js",$data['xmlFile']);
168                         $customChartsArray[$id]['width'] = $data['width'];
169                         $customChartsArray[$id]['height'] = $data['height'];
170
171                         $config = $this->getConfigProperties();
172                         $style['gridLineColor'] = str_replace("0x","#",$config->gridLines);
173                         $style['font-family'] = (string)$config->labelFontFamily;
174                         $style['color'] = str_replace("0x","#",$config->labelFontColor);
175                         $customChartsArray[$id]['css'] = $style;
176                         $xmlStr = $this->processXML($data['xmlFile']);
177                         $xml = new SimpleXMLElement($xmlStr);
178                         $params = $this->getChartConfigParams($xmlStr);
179                         $customChartsArray[$id]['supported'] = ($this->isSupported($xml->properties->type)) ? "true" : "false";
180                         foreach($params as $key => $value) {
181                                 $chartConfig[$key] = $value;
182                         }
183                         $chartConfig['imageExportType'] = $this->image_export_type;
184                         $customChartsArray[$id]['chartConfig'] = $chartConfig;
185                 }
186
187                 return $customChartsArray;
188         }
189
190         function getChartConfigParams($xmlStr) {
191
192                 $xml = new SimpleXMLElement($xmlStr);
193
194                 $chartType = $xml->properties->type;
195                 if($chartType == "pie chart") {
196                         return array ("pieType" => "basic","tip" => "name","chartType" => "pieChart");
197                 } elseif($chartType == "line chart") {
198                         return array ("lineType" => "basic","tip" => "name","chartType" => "lineChart");
199                 } elseif($chartType == "funnel chart 3D") {
200                         return array ("funnelType" => "basic","tip" => "name","chartType" => "funnelChart");
201                 } elseif($chartType == "gauge chart") {
202                         return array ("gaugeType" => "basic","tip" => "name","chartType" => "gaugeChart");
203                 } elseif($chartType == "stacked group by chart") {
204                         return array ("orientation" => "vertical","barType" => "stacked","tip" => "name","chartType" => "barChart");
205                 } elseif($chartType == "group by chart") {
206                         return array("orientation" => "vertical", "barType" => "grouped", "tip" => "title","chartType" => "barChart");
207                 } elseif($chartType == "bar chart") {
208                         return array("orientation" => "vertical", "barType" => "basic", "tip" => "label","chartType" => "barChart");
209                 } elseif ($chartType == "horizontal group by chart") {
210                         return array("orientation" => "horizontal", "barType" => "stacked", "tip" => "name","chartType" => "barChart");
211                 } elseif ($chartType == "horizontal bar chart" || "horizontal") {
212                         return array("orientation" => "horizontal","barType" => "basic","tip" => "label","chartType" => "barChart");
213                 } else {
214                         return array("orientation" => "vertical","barType" => "stacked","tip" => "name","chartType" => "barChart");
215                 }
216         }
217         function getChartDimensions($xmlStr) {
218                 if($this->getNumNodes($xmlStr) > 9 && $this->chartType != "pie chart") {
219                         if($this->chartType == "horizontal group by chart" || $this->chartType == "horizontal bar chart") {
220                                 $height = ($this->getNumNodes($xmlStr) * 60) + 100;
221                                 return array("width"=>$this->width, "height"=>($height));
222                         } else {
223                                 return array("width"=>($this->width * 2), "height"=>$this->height);
224                         }
225                 } else {
226                         return array("width"=>"100%", "height"=>$this->height);
227                 }
228         }
229
230         function checkData($xmlstr) {
231         $xml = new SimpleXMLElement($xmlstr);
232         if(sizeof($xml->data->group) > 0) {
233                         return true;
234                 } else {
235                         return false;
236                 }
237         }
238
239         function getNumNodes($xmlstr) {
240                 $xml = new SimpleXMLElement($xmlstr);
241                 return sizeof($xml->data->group);
242         }
243
244         function buildProperties($xmlstr) {
245                 $content = $this->tab("\"properties\": [\n",1);
246                 $properties = array();
247                 $xml = new SimpleXMLElement($xmlstr);
248                 foreach($xml->properties->children() as $property) {
249                         $properties[] = $this->tab("\"".$property->getName()."\":"."\"".$this->processSpecialChars($property)."\"",2);
250                 }
251                 $content .= $this->tab("{\n",1);
252                 $content .= join(",\n",$properties)."\n";
253                 $content .= $this->tab("}\n",1);
254                 $content .= $this->tab("],\n",1);
255                 return $content;
256         }
257
258         function buildLabelsBarChartStacked($xmlstr) {
259                 $content = $this->tab("\"label\": [\n",1);
260                 $labels = array();
261                 $xml = new SimpleXMLElement($xmlstr);
262                 foreach($xml->data->group[0]->subgroups->group as $group) {
263                         $labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"",2);
264                 }
265                 $content .= join(",\n",$labels)."\n";
266                 $content .= $this->tab("],\n",1);
267                 return $content;
268         }
269
270         function buildLabelsBarChart($xmlstr) {
271
272         // fix for bug42326: if there is label data that is deeper than that of a normal bar chart, render the labels
273         //    like a stacked bar chart, this applies when a stacked chart has been converted in templates_chart.php to a bar chart due to it
274         //    having nothing but single value columns
275         $xml = new SimpleXMLElement($xmlstr);
276         if (count($xml->data->group[0]->subgroups->group) > 0) {
277             return $this->buildLabelsBarChartStacked($xmlstr);
278         }
279
280         $content = $this->tab("\"label\": [\n",1);
281                 $labels = array();
282
283                 foreach($xml->data->group as $group) {
284                         $labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"",2);
285                 }
286                 $labelStr = join(",\n",$labels)."\n";
287                 $content .= $labelStr;
288                 $content .= $this->tab("],\n",1);
289                 return $content;
290         }
291
292         function buildDataBarChartStacked($xmlstr) {
293                 $content = $this->tab("\"values\": [\n",1);
294                 $data = array();
295                 $xml = new SimpleXMLElement($xmlstr);
296                 foreach($xml->data->group as $group) {
297                         $groupcontent = $this->tab("{\n",1);
298                         $groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n",2);
299                         $groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n",2);
300                         $groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\",\n",2);
301                         if (!empty($group->id))
302                         {
303                                 $groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n",2);
304                         }
305                         $subgroupValues = array();
306                         $subgroupValueLabels = array();
307                         $subgroupLinks = array();
308                         foreach($group->subgroups->group as $subgroups) {
309                                 $subgroupValues[] = $this->tab(($subgroups->value == "NULL") ? 0 : $subgroups->value,3);
310                                 $subgroupValueLabels[] = $this->tab("\"".$this->processSpecialChars($subgroups->label)."\"",3);
311                                 $subgroupLinks[] = $this->tab("\"".$subgroups->link."\"",3);
312                         }
313                         $subgroupValuesStr = join(",\n",$subgroupValues)."\n";
314                         $subgroupValueLabelsStr = join(",\n",$subgroupValueLabels)."\n";
315                         $subgroupLinksStr = join(",\n",$subgroupLinks)."\n";
316
317                         $groupcontent .= $this->tab("\"values\": [\n".$subgroupValuesStr,2);
318                         $groupcontent .= $this->tab("],\n",2);
319                         $groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr,2);
320                         $groupcontent .= $this->tab("],\n",2);
321                         $groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr,2);
322                         $groupcontent .= $this->tab("]\n",2);
323                         $groupcontent .= $this->tab("}",1);
324                         $data[] = $groupcontent;
325                 }
326                 $content .= join(",\n",$data)."\n";
327                 $content .= $this->tab("]",1);
328                 return $content;
329         }
330
331         function buildDataBarChartGrouped($xmlstr) {
332                 $content = $this->tab("\"values\": [\n",1);
333                 $data = array();
334                 $xml = new SimpleXMLElement($xmlstr);
335                 foreach($xml->data->group as $group) {
336                         $groupcontent = $this->tab("{\n",1);
337                         $groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n",2);
338                         $groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n",2);
339                         $groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\",\n",2);
340                         if (!empty($group->id))
341                         {
342                                 $groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n",2);
343                         }
344                         $subgroupValues = array();
345                         $subgroupValueLabels = array();
346                         $subgroupLinks = array();
347                         $subgroupTitles = array();
348                         foreach($group->subgroups->group as $subgroups) {
349                                 $subgroupValues[] = $this->tab(($subgroups->value == "NULL") ? 0 : $subgroups->value,3);
350                                 $subgroupValueLabels[] = $this->tab("\"".$subgroups->label."\"",3);
351                                 $subgroupLinks[] = $this->tab("\"".$subgroups->link."\"",3);
352                                 $subgroupTitles[] = $this->tab("\"".$this->processSpecialChars($subgroups->title)."\"",3);
353                         }
354                         $subgroupValuesStr = join(",\n",$subgroupValues)."\n";
355                         $subgroupValueLabelsStr = join(",\n",$subgroupValueLabels)."\n";
356                         $subgroupLinksStr = join(",\n",$subgroupLinks)."\n";
357                         $subgroupTitlesStr = join(",\n",$subgroupTitles)."\n";
358
359                         $groupcontent .= $this->tab("\"values\": [\n".$subgroupValuesStr,2);
360                         $groupcontent .= $this->tab("],\n",2);
361                         $groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr,2);
362                         $groupcontent .= $this->tab("],\n",2);
363                         $groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr,2);
364                         $groupcontent .= $this->tab("],\n",2);
365                         $groupcontent .= $this->tab("\"titles\": [\n".$subgroupTitlesStr,2);
366                         $groupcontent .= $this->tab("]\n",2);
367                         $groupcontent .= $this->tab("}",1);
368                         $data[] = $groupcontent;
369                 }
370                 $content .= join(",\n",$data)."\n";
371                 $content .= $this->tab("]",1);
372                 return $content;
373         }
374
375         function buildDataBarChart($xmlstr) {
376                 $content = $this->tab("\"values\": [\n",1);
377                 $data = array();
378                 $xml = new SimpleXMLElement($xmlstr);
379                 $groupcontent = "";
380                 $groupcontentArr = array();
381
382                 foreach($xml->data->group as $group) {
383                 $groupcontent = $this->tab("{\n",1);
384                 $groupcontent .= $this->tab("\"label\": [\n",2);
385                 $groupcontent .= $this->tab("\"".$this->processSpecialChars($group->title)."\"\n",3);
386                 $groupcontent .= $this->tab("],\n",2);
387                 $groupcontent .= $this->tab("\"values\": [\n",2);
388                 $groupcontent .= $this->tab(($group->value == "NULL") ? 0 : $group->value."\n",3);
389                 $groupcontent .= $this->tab("],\n",2);
390                 if (!empty($group->id))
391                 {
392                         $groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n",2);
393                 }
394                 if($group->label) {
395                         $groupcontent .= $this->tab("\"valuelabels\": [\n",2);
396                         $groupcontent .= $this->tab("\"{$group->label}\"\n",3);
397                         $groupcontent .= $this->tab("],\n",2);
398                 }
399                 $groupcontent .= $this->tab("\"links\": [\n",2);
400                 $groupcontent .= $this->tab("\"{$group->link}\"\n",3);
401                 $groupcontent .= $this->tab("]\n",2);
402                 $groupcontent .= $this->tab("}",1);
403                 $groupcontentArr[] = $groupcontent;
404                 }
405                 $content .= join(",\n",$groupcontentArr)."\n";
406                 $content .= $this->tab("]",1);
407                 return $content;
408         }
409
410           function buildLabelsPieChart($xmlstr) {
411                 $content = $this->tab("\"label\": [\n",1);
412                 $labels = array();
413                 $xml = new SimpleXMLElement($xmlstr);
414                 foreach($xml->data->group as $group) {
415                         $labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"",2);
416                 }
417                 $labelStr = join(",\n",$labels)."\n";
418                 $content .= $labelStr;
419                 $content .= $this->tab("],\n",1);
420                 return $content;
421         }
422
423
424         function buildDataPieChart($xmlstr) {
425                 $content = $this->tab("\"values\": [\n",1);
426                 $data = array();
427                 $xml = new SimpleXMLElement($xmlstr);
428                 $groupcontent = "";
429                 $groupcontentArr = array();
430
431                 foreach($xml->data->group as $group) {
432                 $groupcontent = $this->tab("{\n",1);
433                 $groupcontent .= $this->tab("\"label\": [\n",2);
434                 $groupcontent .= $this->tab("\"".$this->processSpecialChars($group->title)."\"\n",3);
435                 $groupcontent .= $this->tab("],\n",2);
436                 $groupcontent .= $this->tab("\"values\": [\n",2);
437                 $groupcontent .= $this->tab("{$group->value}\n",3);
438                 $groupcontent .= $this->tab("],\n",2);
439                 $groupcontent .= $this->tab("\"valuelabels\": [\n",2);
440                 $groupcontent .= $this->tab("\"{$group->label}\"\n",3);
441                 $groupcontent .= $this->tab("],\n",2);
442                 $groupcontent .= $this->tab("\"links\": [\n",2);
443                 $groupcontent .= $this->tab("\"{$group->link}\"\n",3);
444                 $groupcontent .= $this->tab("]\n",2);
445                 $groupcontent .= $this->tab("}",1);
446                 $groupcontentArr[] = $groupcontent;
447                 }
448
449
450                 $content .= join(",\n",$groupcontentArr)."\n";
451                 $content .= $this->tab("\n]",1);
452                 return $content;
453         }
454
455         function buildLabelsGaugeChart($xmlstr) {
456                 $content = $this->tab("\"label\": [\n",1);
457                 $labels = array();
458                 $xml = new SimpleXMLElement($xmlstr);
459                 foreach($xml->data->group as $group) {
460                         $labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"",2);
461                 }
462                 $labelStr = join(",\n",$labels)."\n";
463                 $content .= $labelStr;
464                 $content .= $this->tab("],\n",1);
465                 return $content;
466         }
467
468         function buildDataGaugeChart($xmlstr) {
469                 $content = $this->tab("\"values\": [\n",1);
470                 $data = array();
471                 $xml = new SimpleXMLElement($xmlstr);
472                 foreach($xml->data->group as $group) {
473                         $groupcontent = $this->tab("{\n",1);
474                         $groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n",2);
475                         $groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n",2);
476                         $finalComma = ($group->title != "GaugePosition") ? "," : "";
477                         $groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\"{$finalComma}\n",2);
478                         $subgroupTitles = array();
479                         $subgroupValues = array();
480                         $subgroupValueLabels = array();
481                         $subgroupLinks = array();
482
483                         if(is_object($group->subgroups->group)) {
484                                 foreach($group->subgroups->group as $subgroups) {
485                                         $subgroupTitles[] = $this->tab("\"".$subgroups->title."\"",3);
486                                         //$subgroupValues[] = $this->tab($subgroups->value,3);
487                                         $subgroupValues[] = $subgroups->value;
488                                         $subgroupValueLabels[] = $this->tab("\"".$subgroups->label."\"",3);
489                                         $subgroupLinks[] = $this->tab("\"".$subgroups->link."\"",3);
490                                 }
491                                 $subgroupTitlesStr = join(",\n",$subgroupTitles)."\n";
492                                 $subgroupValuesStr = join(",\n",$subgroupValues)."\n";
493                                 $subgroupValueLabelsStr = join(",\n",$subgroupValueLabels)."\n";
494                                 $subgroupLinksStr = join(",\n",$subgroupLinks)."\n";
495
496                                 //$groupcontent .= $this->tab("\"labels\": [\n".$subgroupTitlesStr,2);
497                                 //$groupcontent .= $this->tab("],\n",2);
498                                 $val = ((int)$subgroupValues[1] == (int)$subgroupValues[0]) ? $this->tab($subgroupValues[1],3)."\n" : $this->tab($subgroupValues[1] - $subgroupValues[0],3)."\n";
499
500                                 $groupcontent .= $this->tab("\"values\": [\n".$val,2);
501                                 $groupcontent .= $this->tab("],\n",2);
502                                 $groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr,2);
503                                 $groupcontent .= $this->tab("]\n",2);
504                                 //$groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr,2);
505                                 //$groupcontent .= $this->tab("]\n",2);
506
507                         }
508
509                                 $groupcontent .= $this->tab("}",1);
510                                 $data[] = $groupcontent;
511
512                 }
513
514                 $content .= join(",\n",$data)."\n";
515
516
517                 $content .= $this->tab("]",1);
518                 return $content;
519         }
520
521
522         function getConfigProperties() {
523                 $path = SugarThemeRegistry::current()->getImageURL('sugarColors.xml',false);
524
525                 if(!file_exists($path)) {
526                         $GLOBALS['log']->debug("Cannot open file ($path)");
527                 }
528                 $xmlstr = file_get_contents($path);
529                 $xml = new SimpleXMLElement($xmlstr);
530                 return $xml->charts;
531         }
532
533         function buildChartColors() {
534
535                 $content = $this->tab("\"color\": [\n",1);
536                 $colorArr = array();
537                 $xml = $this->getConfigProperties();
538                 $colors = ($this->chartType == "gauge chart") ? $xml->gaugeChartElementColors->color : $xml->chartElementColors->color;
539                 foreach($colors as $color) {
540                         $colorArr[] = $this->tab("\"".str_replace("0x","#",$color)."\"",2);
541                 }
542                 $content .= join(",\n",$colorArr)."\n";
543                 $content .= $this->tab("],\n",1);
544
545                 return $content;
546
547         }
548
549         function buildJson($xmlstr){
550                 if($this->checkData($xmlstr)) {
551                         $content = "{\n";
552                         if ($this->chartType == "pie chart" || $this->chartType == "funnel chart 3D") {
553                                 $content .= $this->buildProperties($xmlstr);
554                                 $content .= $this->buildLabelsPieChart($xmlstr);
555                                 $content .= $this->buildChartColors();
556                                 $content .= $this->buildDataPieChart($xmlstr);
557                         }
558                         elseif ($this->chartType == "gauge chart") {
559                                 $content .= $this->buildProperties($xmlstr);
560                                 $content .= $this->buildLabelsGaugeChart($xmlstr);
561                                 $content .= $this->buildChartColors();
562                                 $content .= $this->buildDataGaugeChart($xmlstr);
563                         }
564                         elseif ($this->chartType == "horizontal bar chart" || $this->chartType == "bar chart") {
565                                 $content .= $this->buildProperties($xmlstr);
566                                 $content .= $this->buildLabelsBarChart($xmlstr);
567                                 $content .= $this->buildChartColors();
568                                 $content .= $this->buildDataBarChart($xmlstr);
569                         }
570                         elseif ($this->chartType == "group by chart") {
571                                 $content .= $this->buildProperties($xmlstr);
572                                 $content .= $this->buildLabelsBarChartStacked($xmlstr);
573                                 $content .= $this->buildChartColors();
574                                 $content .= $this->buildDataBarChartGrouped($xmlstr);
575                         } else {
576                                 $content .= $this->buildProperties($xmlstr);
577                                 $content .= $this->buildLabelsBarChartStacked($xmlstr);
578                                 $content .= $this->buildChartColors();
579                                 $content .= $this->buildDataBarChartStacked($xmlstr);
580                         }
581                         $content .= "\n}";
582                         return $content;
583                 } else {
584                         return "No Data";
585                 }
586         }
587
588         function buildHTMLLegend($xmlFile) {
589                 $xmlstr = $this->processXML($xmlFile);
590                 $xml = new SimpleXMLElement($xmlstr);
591                 $this->chartType = $xml->properties->type;
592                 $html = "<table align=\"left\" cellpadding=\"2\" cellspacing=\"2\">";
593
594         if (
595             $this->chartType == "group by chart"
596             || $this->chartType == "horizontal group by chart"
597             || $this->chartType == 'line chart'
598             || $this->chartType == 'stacked group by chart'
599         )
600         {
601                         $groups = $xml->data->group[0]->subgroups->group;
602                         $items = (sizeof($xml->data->group[0]->subgroups->group) <= 5) ? 5 : sizeof($xml->data->group[0]->subgroups->group);
603                 } else {
604             if ($this->chartType == "funnel chart 3D") {
605                 // reverse legend
606                 $groups = array();
607                 foreach($xml->data->group as $group) {
608                     array_unshift($groups, $group);
609                 }
610             } else {
611                 $groups = $xml->data->group;
612             }
613                         $items = (sizeof($xml->data->group) <= 5) ? 5 : sizeof($xml->data->group);
614                 }
615
616                 $rows = ceil($items/5);
617                 $fullItems = $rows * 5;
618                 $remainder = ($items < $fullItems) ? $fullItems - $items : 0;
619                 $i = 0;
620                 $x = 0;
621
622
623                 $colorArr = array();
624                 $xmlColors = $this->getConfigProperties();
625                 $colors = ($this->chartType == "gauge chart") ? $xmlColors->gaugeChartElementColors->color : $xmlColors->chartElementColors->color;
626
627                 foreach($colors as $color) {
628                         $colorArr[] = str_replace("0x","#",$color);
629                 }
630
631         $isTrClosed = false;
632                 foreach($groups as $group) {
633                         if($i == 5) {$i = 0;}
634                         $html .= ($i == 0) ? "<tr>" : "";
635                         $html .= "<td width=\"50\">";
636                         $html .= "<div style=\"background-color:".$colorArr[$x].";\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>";
637                         $html .= "</td>";
638                         $html .= "<td>";
639                         $html .= $group->title;
640                         $html .= "</td>";
641                         $html .= ($x+1 == $items) ? "<td colspan=".($remainder*2)."></td>" : "";
642             if ($i == 4)
643             {
644                 $html .= "</tr>";
645                 $isTrClosed = true;
646             }
647             else
648             {
649                 $isTrClosed = false;
650             }
651                         $x++;
652                         $i++;
653                 }
654         if ($isTrClosed == false)
655         {
656             $html .= '</tr>';
657         }
658
659                 $html .= "</table>";
660                 return $html;
661         }
662
663         function saveJsonFile($jsonContents) {
664                 $this->jsonFilename = str_replace(".xml",".js",$this->xmlFile);
665                 //$jsonContents = $GLOBALS['locale']->translateCharset($jsonContents, 'UTF-8', 'UTF-16LE');
666
667                 // open file
668                 if (!$fh = sugar_fopen($this->jsonFilename, 'w')) {
669                         $GLOBALS['log']->debug("Cannot open file ($this->jsonFilename)");
670                         return;
671                 }
672
673                 // write the contents to the file
674                 if (fwrite($fh,$jsonContents) === FALSE) {
675                         $GLOBALS['log']->debug("Cannot write to file ($this->jsonFilename)");
676                         return false;
677                 }
678
679                 $GLOBALS['log']->debug("Success, wrote ($jsonContents) to file ($this->jsonFilename)");
680
681                 fclose($fh);
682                 return true;
683         }
684
685         function get_image_cache_file_name ($xmlFile,$ext = ".png") {
686                 $filename = str_replace("/xml/","/images/",str_replace(".xml",$ext,$xmlFile));
687
688                 return $filename;
689         }
690
691
692         function getXMLChartProperties($xmlStr) {
693                 $props = array();
694                 $xml = new SimpleXMLElement($xmlstr);
695                 foreach($xml->properties->children() as $properties) {
696                         $props[$properties->getName()] = $properties;
697                 }
698                 return $props;
699         }
700
701         function processSpecialChars($str) {
702                 return addslashes(html_entity_decode($str,ENT_QUOTES));
703         }
704
705         function processXML($xmlFile) {
706
707                 if(!file_exists($xmlFile)) {
708                         $GLOBALS['log']->debug("Cannot open file ($xmlFile)");
709                 }
710
711                 $pattern = array();
712                 $replacement = array();
713                 $content = file_get_contents($xmlFile);
714                 $content = $GLOBALS['locale']->translateCharset($content,'UTF-16LE', 'UTF-8');
715                 $pattern[] = '/\<link\>([a-zA-Z0-9#?&%.;\[\]\/=+_-\s]+)\<\/link\>/e';
716                 $replacement[] = "'<link>'.urlencode(\"$1\").'</link>'";
717 //              $pattern[] = '/NULL/e';
718 //              $replacement[] = "";
719                 return preg_replace($pattern,$replacement, $content);
720         }
721
722
723 }
724
725 ?>