0
0
mirror of https://github.com/salesagility/SuiteCRM.git synced 2024-12-22 12:28:31 +00:00
salesagility_SuiteCRM/include/SugarCharts/JsChart.php
Craig Panton 73ded274ee Merge remote-tracking branch 'remotes/origin/hotfix-7.10.x' into hotfix
# Conflicts:
#	.codecov.yml
#	.travis.yml
#	composer.lock
#	include/database/DBManager.php
#	include/phpmailer/class.phpmailer.php
#	include/phpmailer/extras/htmlfilter.php
#	include/tcpdf/fonts/utils/makefont.php
#	modules/AOD_Index/Lib/Zend/Search/Exception.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Text.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Text/CaseInsensitive.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/TextNum.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/TextNum/CaseInsensitive.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8/CaseInsensitive.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8Num/CaseInsensitive.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Token.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter/LowerCase.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter/LowerCaseUtf8.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter/ShortWords.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter/StopWords.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Document/Docx.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Document/Exception.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Document/OpenXml.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Document/Pptx.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Document/Xlsx.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Exception.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/FSM.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/FSMAction.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Field.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Index/DictionaryLoader.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Index/DocsFilter.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Index/FieldInfo.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Index/Term.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Index/TermInfo.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Index/TermsPriorityQueue.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Interface/MultiSearcher.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/LockManager.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/MultiSearcher.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/PriorityQueue.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/BooleanExpressionRecognizer.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Highlighter/Default.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Empty.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Insignificant.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Preprocessing.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Range.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Term.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Wildcard.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryEntry.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryHit.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryParserContext.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryParserException.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryToken.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Similarity.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Weight.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Weight/Empty.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Storage/Directory.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Storage/Directory/Filesystem.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Storage/File/Filesystem.php
#	modules/AOD_Index/Lib/Zend/Search/Lucene/Storage/File/Memory.php
#	modules/Administration/metadata/adminpaneldefs.php
#	modules/Audit/Audit.php
#	modules/Calendar/CalendarDisplay.php
#	modules/Calls/Call.php
#	modules/Contacts/BusinessCard.php
#	modules/UpgradeWizard/language/en_us.lang.php
#	modules/Users/authentication/LDAPAuthenticate/LDAPAuthenticateUser.php
#	service/v3/SugarWebServiceImplv3.php
#	service/v4/SugarWebServiceUtilv4.php
#	tests/unit/phpunit/data/SugarBeanTest.php
#	themes/SuiteP/css/Dawn/style.css
#	themes/SuiteP/css/Day/style.css
#	themes/SuiteP/css/Dusk/style.css
#	themes/SuiteP/css/Night/style.css
2019-10-23 11:10:20 +01:00

744 lines
30 KiB
PHP
Executable File

<?php
/**
*
* SugarCRM Community Edition is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
*
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
* Copyright (C) 2011 - 2018 SalesAgility Ltd.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
* reasonably feasible for technical reasons, the Appropriate Legal Notices must
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
*/
require_once("include/SugarCharts/SugarChart.php");
class JsChart extends SugarChart
{
protected $ss;
public $xmlFile;
public $jsonFilename;
public $chartId;
public $width;
public $height;
public $chartType;
public function __construct()
{
parent::__construct();
}
public function isSupported($chartType)
{
$charts = array(
"stacked group by chart",
"group by chart",
"bar chart",
"horizontal group by chart",
"horizontal",
"horizontal bar chart",
"pie chart",
"gauge chart",
"funnel chart 3D",
"line chart",
);
if (in_array($chartType, $charts)) {
return true;
} else {
return false;
}
}
public function tab($str, $depth)
{
// $str = preg_replace('/(<\w+>)(.*)(<\/\w+>)/e', "'\\1'.htmlentities(from_html('\\2')).'\\3'", $str);
return str_repeat("\t", $depth) . $str . "\n";
}
public function display($name, $xmlFile, $width='320', $height='480', $resize=false)
{
$this->chartId = $name;
$this->height = $height;
$this->width = $width;
$this->xmlFile = $xmlFile;
$this->chartType = $this->chart_properties['type'];
$style = array();
$chartConfig = array();
try {
$xmlStr = $this->processXML($this->xmlFile);
$json = $this->buildJson($xmlStr);
} catch (Exception $e) {
$GLOBALS['log']->fatal("Unable to return chart data, invalid xml for file {$this->xmlFile}");
return '';
}
$this->saveJsonFile($json);
$this->ss->assign("chartId", $this->chartId);
$this->ss->assign("filename", $this->jsonFilename);
global $mod_strings, $app_strings;
if (isset($mod_strings['LBL_REPORT_SHOW_CHART'])) {
$this->ss->assign("showchart", $mod_strings['LBL_REPORT_SHOW_CHART']);
}
$dimensions = $this->getChartDimensions($xmlStr);
$this->ss->assign("width", $dimensions['width']);
$this->ss->assign("height", $dimensions['height']);
$config = $this->getConfigProperties();
$style['gridLineColor'] = str_replace("0x", "#", $config->gridLines);
$style['font-family'] = $config->labelFontFamily;
$style['color'] = str_replace("0x", "#", $config->labelFontColor);
$this->ss->assign("css", $style);
foreach ($this->getChartConfigParams($xmlStr) as $key => $value) {
$chartConfig[$key] = $value;
}
$chartConfig['imageExportType'] = $this->image_export_type;
$this->ss->assign("config", $chartConfig);
if ($json == "No Data") {
$this->ss->assign("error", $app_strings['LBL_NO_DATA']);
}
if (!$this->isSupported($this->chartType)) {
$this->ss->assign("error", "Unsupported Chart Type");
}
}
public function getDashletScript($id, $xmlFile="")
{
global $sugar_config, $current_user, $current_language;
$this->id = $id;
$this->chartId = $id;
$this->xmlFile = (!$xmlFile) ? sugar_cached("xml/".$current_user->getUserPrivGuid()."_{$this->id}.xml") : $xmlFile;
$style = array();
$chartConfig = array();
$this->ss->assign("chartId", $this->chartId);
$this->ss->assign("filename", str_replace(".xml", ".js", $this->xmlFile));
$config = $this->getConfigProperties();
$style['gridLineColor'] = str_replace("0x", "#", $config->gridLines);
$style['font-family'] = $config->labelFontFamily;
$style['color'] = str_replace("0x", "#", $config->labelFontColor);
$this->ss->assign("css", $style);
$xmlStr = $this->processXML($this->xmlFile);
foreach ($this->getChartConfigParams($xmlStr) as $key => $value) {
$chartConfig[$key] = $value;
}
$chartConfig['imageExportType'] = $this->image_export_type;
$this->ss->assign("config", $chartConfig);
}
public function chartArray($chartsArray)
{
$customChartsArray = array();
$style = array();
$chartConfig = array();
foreach ($chartsArray as $id => $data) {
$customChartsArray[$id] = array();
$customChartsArray[$id]['chartId'] = $id;
$customChartsArray[$id]['filename'] = str_replace(".xml", ".js", $data['xmlFile']);
$customChartsArray[$id]['width'] = $data['width'];
$customChartsArray[$id]['height'] = $data['height'];
$config = $this->getConfigProperties();
$style['gridLineColor'] = str_replace("0x", "#", $config->gridLines);
$style['font-family'] = (string)$config->labelFontFamily;
$style['color'] = str_replace("0x", "#", $config->labelFontColor);
$customChartsArray[$id]['css'] = $style;
$xmlStr = $this->processXML($data['xmlFile']);
$xml = new SimpleXMLElement($xmlStr);
$params = $this->getChartConfigParams($xmlStr);
$customChartsArray[$id]['supported'] = ($this->isSupported($xml->properties->type)) ? "true" : "false";
foreach ($params as $key => $value) {
$chartConfig[$key] = $value;
}
$chartConfig['imageExportType'] = $this->image_export_type;
$customChartsArray[$id]['chartConfig'] = $chartConfig;
}
return $customChartsArray;
}
public function getChartConfigParams($xmlStr)
{
$xml = new SimpleXMLElement($xmlStr);
$chartType = $xml->properties->type;
if ($chartType == "pie chart") {
return array("pieType" => "basic","tip" => "name","chartType" => "pieChart");
} elseif ($chartType == "line chart") {
return array("lineType" => "basic","tip" => "name","chartType" => "lineChart");
} elseif ($chartType == "funnel chart 3D") {
return array("funnelType" => "basic","tip" => "name","chartType" => "funnelChart");
} elseif ($chartType == "gauge chart") {
return array("gaugeType" => "basic","tip" => "name","chartType" => "gaugeChart");
} elseif ($chartType == "stacked group by chart") {
return array("orientation" => "vertical","barType" => "stacked","tip" => "name","chartType" => "barChart");
} elseif ($chartType == "group by chart") {
return array("orientation" => "vertical", "barType" => "grouped", "tip" => "title","chartType" => "barChart");
} elseif ($chartType == "bar chart") {
return array("orientation" => "vertical", "barType" => "basic", "tip" => "label","chartType" => "barChart");
} elseif ($chartType == "horizontal group by chart") {
return array("orientation" => "horizontal", "barType" => "stacked", "tip" => "name","chartType" => "barChart");
} elseif ($chartType == "horizontal bar chart" || "horizontal") {
return array("orientation" => "horizontal","barType" => "basic","tip" => "label","chartType" => "barChart");
} else {
return array("orientation" => "vertical","barType" => "stacked","tip" => "name","chartType" => "barChart");
}
}
public function getChartDimensions($xmlStr)
{
if ($this->getNumNodes($xmlStr) > 9 && $this->chartType != "pie chart") {
if ($this->chartType == "horizontal group by chart" || $this->chartType == "horizontal bar chart") {
$height = ($this->getNumNodes($xmlStr) * 60) + 100;
return array("width"=>$this->width, "height"=>($height));
} else {
return array("width"=>($this->width * 2), "height"=>$this->height);
}
} else {
return array("width"=>"100%", "height"=>$this->height);
}
}
public function checkData($xmlstr)
{
$xml = new SimpleXMLElement($xmlstr);
if (count($xml->data->group) > 0) {
return true;
} else {
return false;
}
}
public function getNumNodes($xmlstr)
{
$xml = new SimpleXMLElement($xmlstr);
return count($xml->data->group);
}
public function buildProperties($xmlstr)
{
$content = $this->tab("\"properties\": [\n", 1);
$properties = array();
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->properties->children() as $property) {
$properties[] = $this->tab("\"".$property->getName()."\":"."\"".$this->processSpecialChars($property)."\"", 2);
}
$content .= $this->tab("{\n", 1);
$content .= implode(",\n", $properties)."\n";
$content .= $this->tab("}\n", 1);
$content .= $this->tab("],\n", 1);
return $content;
}
public function buildLabelsBarChartStacked($xmlstr)
{
$content = $this->tab("\"label\": [\n", 1);
$labels = array();
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->data->group[0]->subgroups->group as $group) {
$labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"", 2);
}
$content .= implode(",\n", $labels)."\n";
$content .= $this->tab("],\n", 1);
return $content;
}
public function buildLabelsBarChart($xmlstr)
{
// fix for bug42326: if there is label data that is deeper than that of a normal bar chart, render the labels
// 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
// having nothing but single value columns
$xml = new SimpleXMLElement($xmlstr);
if (count($xml->data->group[0]->subgroups->group) > 0) {
return $this->buildLabelsBarChartStacked($xmlstr);
}
$content = $this->tab("\"label\": [\n", 1);
$labels = array();
foreach ($xml->data->group as $group) {
$labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"", 2);
}
$labelStr = implode(",\n", $labels)."\n";
$content .= $labelStr;
$content .= $this->tab("],\n", 1);
return $content;
}
public function buildDataBarChartStacked($xmlstr)
{
$content = $this->tab("\"values\": [\n", 1);
$data = array();
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->data->group as $group) {
$groupcontent = $this->tab("{\n", 1);
$groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n", 2);
$groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n", 2);
$groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\",\n", 2);
if (!empty($group->id)) {
$groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n", 2);
}
$subgroupValues = array();
$subgroupValueLabels = array();
$subgroupLinks = array();
foreach ($group->subgroups->group as $subgroups) {
$subgroupValues[] = $this->tab(($subgroups->value == "NULL") ? 0 : $subgroups->value, 3);
$subgroupValueLabels[] = $this->tab("\"".$this->processSpecialChars($subgroups->label)."\"", 3);
$subgroupLinks[] = $this->tab("\"".$subgroups->link."\"", 3);
}
$subgroupValuesStr = implode(",\n", $subgroupValues)."\n";
$subgroupValueLabelsStr = implode(",\n", $subgroupValueLabels)."\n";
$subgroupLinksStr = implode(",\n", $subgroupLinks)."\n";
$groupcontent .= $this->tab("\"values\": [\n".$subgroupValuesStr, 2);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr, 2);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr, 2);
$groupcontent .= $this->tab("]\n", 2);
$groupcontent .= $this->tab("}", 1);
$data[] = $groupcontent;
}
$content .= implode(",\n", $data)."\n";
$content .= $this->tab("]", 1);
return $content;
}
public function buildDataBarChartGrouped($xmlstr)
{
$content = $this->tab("\"values\": [\n", 1);
$data = array();
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->data->group as $group) {
$groupcontent = $this->tab("{\n", 1);
$groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n", 2);
$groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n", 2);
$groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\",\n", 2);
if (!empty($group->id)) {
$groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n", 2);
}
$subgroupValues = array();
$subgroupValueLabels = array();
$subgroupLinks = array();
$subgroupTitles = array();
foreach ($group->subgroups->group as $subgroups) {
$subgroupValues[] = $this->tab(($subgroups->value == "NULL") ? 0 : $subgroups->value, 3);
$subgroupValueLabels[] = $this->tab("\"".$subgroups->label."\"", 3);
$subgroupLinks[] = $this->tab("\"".$subgroups->link."\"", 3);
$subgroupTitles[] = $this->tab("\"".$this->processSpecialChars($subgroups->title)."\"", 3);
}
$subgroupValuesStr = implode(",\n", $subgroupValues)."\n";
$subgroupValueLabelsStr = implode(",\n", $subgroupValueLabels)."\n";
$subgroupLinksStr = implode(",\n", $subgroupLinks)."\n";
$subgroupTitlesStr = implode(",\n", $subgroupTitles)."\n";
$groupcontent .= $this->tab("\"values\": [\n".$subgroupValuesStr, 2);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr, 2);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr, 2);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"titles\": [\n".$subgroupTitlesStr, 2);
$groupcontent .= $this->tab("]\n", 2);
$groupcontent .= $this->tab("}", 1);
$data[] = $groupcontent;
}
$content .= implode(",\n", $data)."\n";
$content .= $this->tab("]", 1);
return $content;
}
public function buildDataBarChart($xmlstr)
{
$content = $this->tab("\"values\": [\n", 1);
$data = array();
$xml = new SimpleXMLElement($xmlstr);
$groupcontent = "";
$groupcontentArr = array();
foreach ($xml->data->group as $group) {
$groupcontent = $this->tab("{\n", 1);
$groupcontent .= $this->tab("\"label\": [\n", 2);
$groupcontent .= $this->tab("\"".$this->processSpecialChars($group->title)."\"\n", 3);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"values\": [\n", 2);
$groupcontent .= $this->tab(($group->value == "NULL") ? 0 : $group->value."\n", 3);
$groupcontent .= $this->tab("],\n", 2);
if (!empty($group->id)) {
$groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n", 2);
}
if ($group->label) {
$groupcontent .= $this->tab("\"valuelabels\": [\n", 2);
$groupcontent .= $this->tab("\"{$group->label}\"\n", 3);
$groupcontent .= $this->tab("],\n", 2);
}
$groupcontent .= $this->tab("\"links\": [\n", 2);
$groupcontent .= $this->tab("\"{$group->link}\"\n", 3);
$groupcontent .= $this->tab("]\n", 2);
$groupcontent .= $this->tab("}", 1);
$groupcontentArr[] = $groupcontent;
}
$content .= implode(",\n", $groupcontentArr)."\n";
$content .= $this->tab("]", 1);
return $content;
}
public function buildLabelsPieChart($xmlstr)
{
$content = $this->tab("\"label\": [\n", 1);
$labels = array();
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->data->group as $group) {
$labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"", 2);
}
$labelStr = implode(",\n", $labels)."\n";
$content .= $labelStr;
$content .= $this->tab("],\n", 1);
return $content;
}
public function buildDataPieChart($xmlstr)
{
$content = $this->tab("\"values\": [\n", 1);
$data = array();
$xml = new SimpleXMLElement($xmlstr);
$groupcontent = "";
$groupcontentArr = array();
foreach ($xml->data->group as $group) {
$groupcontent = $this->tab("{\n", 1);
$groupcontent .= $this->tab("\"label\": [\n", 2);
$groupcontent .= $this->tab("\"".$this->processSpecialChars($group->title)."\"\n", 3);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"values\": [\n", 2);
$groupcontent .= $this->tab("{$group->value}\n", 3);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"valuelabels\": [\n", 2);
$groupcontent .= $this->tab("\"{$group->label}\"\n", 3);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"links\": [\n", 2);
$groupcontent .= $this->tab("\"{$group->link}\"\n", 3);
$groupcontent .= $this->tab("]\n", 2);
$groupcontent .= $this->tab("}", 1);
$groupcontentArr[] = $groupcontent;
}
$content .= implode(",\n", $groupcontentArr)."\n";
$content .= $this->tab("\n]", 1);
return $content;
}
public function buildLabelsGaugeChart($xmlstr)
{
$content = $this->tab("\"label\": [\n", 1);
$labels = array();
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->data->group as $group) {
$labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"", 2);
}
$labelStr = implode(",\n", $labels)."\n";
$content .= $labelStr;
$content .= $this->tab("],\n", 1);
return $content;
}
public function buildDataGaugeChart($xmlstr)
{
$content = $this->tab("\"values\": [\n", 1);
$data = array();
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->data->group as $group) {
$groupcontent = $this->tab("{\n", 1);
$groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n", 2);
$groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n", 2);
$finalComma = ($group->title != "GaugePosition") ? "," : "";
$groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\"{$finalComma}\n", 2);
$subgroupTitles = array();
$subgroupValues = array();
$subgroupValueLabels = array();
$subgroupLinks = array();
if (is_object($group->subgroups->group)) {
foreach ($group->subgroups->group as $subgroups) {
$subgroupTitles[] = $this->tab("\"".$subgroups->title."\"", 3);
//$subgroupValues[] = $this->tab($subgroups->value,3);
$subgroupValues[] = $subgroups->value;
$subgroupValueLabels[] = $this->tab("\"".$subgroups->label."\"", 3);
$subgroupLinks[] = $this->tab("\"".$subgroups->link."\"", 3);
}
$subgroupTitlesStr = implode(",\n", $subgroupTitles)."\n";
$subgroupValuesStr = implode(",\n", $subgroupValues)."\n";
$subgroupValueLabelsStr = implode(",\n", $subgroupValueLabels)."\n";
$subgroupLinksStr = implode(",\n", $subgroupLinks)."\n";
//$groupcontent .= $this->tab("\"labels\": [\n".$subgroupTitlesStr,2);
//$groupcontent .= $this->tab("],\n",2);
$val = ((int)$subgroupValues[1] == (int)$subgroupValues[0]) ? $this->tab($subgroupValues[1], 3)."\n" : $this->tab($subgroupValues[1] - $subgroupValues[0], 3)."\n";
$groupcontent .= $this->tab("\"values\": [\n".$val, 2);
$groupcontent .= $this->tab("],\n", 2);
$groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr, 2);
$groupcontent .= $this->tab("]\n", 2);
//$groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr,2);
//$groupcontent .= $this->tab("]\n",2);
}
$groupcontent .= $this->tab("}", 1);
$data[] = $groupcontent;
}
$content .= implode(",\n", $data)."\n";
$content .= $this->tab("]", 1);
return $content;
}
public function getConfigProperties()
{
$path = SugarThemeRegistry::current()->getImageURL('sugarColors.xml', false);
if (!file_exists($path)) {
$GLOBALS['log']->debug("Cannot open file ($path)");
}
$xmlstr = file_get_contents($path);
$xml = new SimpleXMLElement($xmlstr);
return $xml->charts;
}
public function buildChartColors()
{
$content = $this->tab("\"color\": [\n", 1);
$colorArr = array();
$xml = $this->getConfigProperties();
$colors = ($this->chartType == "gauge chart") ? $xml->gaugeChartElementColors->color : $xml->chartElementColors->color;
foreach ($colors as $color) {
$colorArr[] = $this->tab("\"".str_replace("0x", "#", $color)."\"", 2);
}
$content .= implode(",\n", $colorArr)."\n";
$content .= $this->tab("],\n", 1);
return $content;
}
public function buildJson($xmlstr)
{
if ($this->checkData($xmlstr)) {
$content = "{\n";
if ($this->chartType == "pie chart" || $this->chartType == "funnel chart 3D") {
$content .= $this->buildProperties($xmlstr);
$content .= $this->buildLabelsPieChart($xmlstr);
$content .= $this->buildChartColors();
$content .= $this->buildDataPieChart($xmlstr);
} elseif ($this->chartType == "gauge chart") {
$content .= $this->buildProperties($xmlstr);
$content .= $this->buildLabelsGaugeChart($xmlstr);
$content .= $this->buildChartColors();
$content .= $this->buildDataGaugeChart($xmlstr);
} elseif ($this->chartType == "horizontal bar chart" || $this->chartType == "bar chart") {
$content .= $this->buildProperties($xmlstr);
$content .= $this->buildLabelsBarChart($xmlstr);
$content .= $this->buildChartColors();
$content .= $this->buildDataBarChart($xmlstr);
} elseif ($this->chartType == "group by chart") {
$content .= $this->buildProperties($xmlstr);
$content .= $this->buildLabelsBarChartStacked($xmlstr);
$content .= $this->buildChartColors();
$content .= $this->buildDataBarChartGrouped($xmlstr);
} else {
$content .= $this->buildProperties($xmlstr);
$content .= $this->buildLabelsBarChartStacked($xmlstr);
$content .= $this->buildChartColors();
$content .= $this->buildDataBarChartStacked($xmlstr);
}
$content .= "\n}";
return $content;
} else {
return "No Data";
}
}
public function buildHTMLLegend($xmlFile)
{
$xmlstr = $this->processXML($xmlFile);
$xml = new SimpleXMLElement($xmlstr);
$this->chartType = $xml->properties->type;
$html = "<table align=\"left\" cellpadding=\"2\" cellspacing=\"2\">";
if (
$this->chartType == "group by chart"
|| $this->chartType == "horizontal group by chart"
|| $this->chartType == 'line chart'
|| $this->chartType == 'stacked group by chart'
) {
$groups = $xml->data->group[0]->subgroups->group;
$items = (count($xml->data->group[0]->subgroups->group) <= 5) ? 5 : count($xml->data->group[0]->subgroups->group);
} else {
if ($this->chartType == "funnel chart 3D") {
// reverse legend
$groups = array();
foreach ($xml->data->group as $group) {
array_unshift($groups, $group);
}
} else {
$groups = $xml->data->group;
}
$items = (count($xml->data->group) <= 5) ? 5 : count($xml->data->group);
}
$rows = ceil($items/5);
$fullItems = $rows * 5;
$remainder = ($items < $fullItems) ? $fullItems - $items : 0;
$i = 0;
$x = 0;
$colorArr = array();
$xmlColors = $this->getConfigProperties();
$colors = ($this->chartType == "gauge chart") ? $xmlColors->gaugeChartElementColors->color : $xmlColors->chartElementColors->color;
foreach ($colors as $color) {
$colorArr[] = str_replace("0x", "#", $color);
}
$isTrClosed = false;
foreach ($groups as $group) {
if ($i == 5) {
$i = 0;
}
$html .= ($i == 0) ? "<tr>" : "";
$html .= "<td width=\"50\">";
$html .= "<div style=\"background-color:".$colorArr[$x].";\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>";
$html .= "</td>";
$html .= "<td>";
$html .= $group->title;
$html .= "</td>";
$html .= ($x+1 == $items) ? "<td colspan=".($remainder*2)."></td>" : "";
if ($i == 4) {
$html .= "</tr>";
$isTrClosed = true;
} else {
$isTrClosed = false;
}
$x++;
$i++;
}
if ($isTrClosed == false) {
$html .= '</tr>';
}
$html .= "</table>";
return $html;
}
public function saveJsonFile($jsonContents)
{
$this->jsonFilename = str_replace(".xml", ".js", $this->xmlFile);
//$jsonContents = $GLOBALS['locale']->translateCharset($jsonContents, 'UTF-8', 'UTF-16LE');
// open file
if (!$fh = sugar_fopen($this->jsonFilename, 'w')) {
$GLOBALS['log']->debug("Cannot open file ($this->jsonFilename)");
return;
}
// write the contents to the file
if (fwrite($fh, $jsonContents) === false) {
$GLOBALS['log']->debug("Cannot write to file ($this->jsonFilename)");
return false;
}
$GLOBALS['log']->debug("Success, wrote ($jsonContents) to file ($this->jsonFilename)");
fclose($fh);
return true;
}
public function get_image_cache_file_name($xmlFile, $ext = ".png")
{
$filename = str_replace("/xml/", "/images/", str_replace(".xml", $ext, $xmlFile));
return $filename;
}
public function getXMLChartProperties($xmlStr)
{
$props = array();
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->properties->children() as $properties) {
$props[$properties->getName()] = $properties;
}
return $props;
}
public function processSpecialChars($str)
{
return addslashes(html_entity_decode($str, ENT_QUOTES));
}
public function processXML($xmlFile)
{
if (!file_exists($xmlFile)) {
$GLOBALS['log']->debug("Cannot open file ($xmlFile)");
}
$pattern = array();
$replacement = array();
$content = file_get_contents($xmlFile);
$content = $GLOBALS['locale']->translateCharset($content, 'UTF-16LE', 'UTF-8');
/*
* Fix to Bug 1934 https://suitecrm.com/forum/bug-tracker/1934-unable-to-return-chart-data-invalid-xml-for-file-cache-xml
*
* This compensates for changes to PCRE Extension for PHP > 5.5.1
* Where original Regex expression failed during compilation time using
* pattern[] = '/\<link\>([a-zA-Z0-9#?&%.;\[\]\/=+_-\s]+)\<\/link\>/e';
*
* Replacement regex $pattern applied
*/
$return = preg_replace_callback('/\<link\>([a-zA-Z0-9#?&%.;\[\]\/=+\s\-\_]+)\<\/link\>/', function ($m) {
return '<link>'.urlencode($m[1]).'</link>';
}, $content);
return $return;
}
}