control.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <?php
  2. /**
  3. * The control file of chart module of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
  6. * @license ZPL (http://zpl.pub/page/zplv12.html)
  7. * @author Chunsheng Wang <chunsheng@cnezsoft.com>
  8. * @package chart
  9. * @version $Id: model.php 5086 2013-07-10 02:25:22Z wyd621@gmail.com $
  10. * @link https://www.zentao.net
  11. */
  12. class chart extends control
  13. {
  14. /**
  15. * __construct method.
  16. *
  17. * @access public
  18. * @return void
  19. * @param string $moduleName
  20. * @param string $methodName
  21. * @param string $appName
  22. */
  23. public function __construct($moduleName = '', $methodName = '', $appName = '')
  24. {
  25. parent::__construct($moduleName, $methodName, $appName);
  26. $this->dao->exec("SET @@sql_mode=''");
  27. }
  28. /**
  29. * 预览图表。
  30. * Preview charts of a group.
  31. *
  32. * @param int $dimensionID
  33. * @param int $groupID
  34. * @access public
  35. * @return void
  36. */
  37. public function preview($dimensionID = 0, $groupID = 0)
  38. {
  39. $dimensionID = $this->loadModel('dimension')->getDimension($dimensionID);
  40. if(!is_numeric($groupID)) $groupID = 0;
  41. if(!$groupID) $groupID = $this->chart->getFirstGroup($dimensionID);
  42. $charts = array();
  43. if($_POST)
  44. {
  45. if($this->post->charts)
  46. {
  47. /* 选中多个图表查看。*/
  48. /* Select multiple charts to view. */
  49. $charts = $this->getChartsToView($this->post->charts);
  50. }
  51. else if($this->post->groupID && $this->post->chartID)
  52. {
  53. /* 更改一个图表的过滤条件。*/
  54. /* Change filter conditions of a chart. */
  55. $chart = $this->getChartToFilter((int)$this->post->groupID, (int)$this->post->chartID, $this->post->filterValues ? $this->post->filterValues : array());
  56. if($chart) $charts[] = $chart;
  57. }
  58. }
  59. if(!$charts) $charts = $this->chart->getDefaultCharts($groupID);
  60. $this->view->title = $this->lang->chart->preview;
  61. $this->view->groups = $this->loadModel('tree')->getGroupPairs($dimensionID, 0, 1);
  62. $this->view->treeMenu = $this->chart->getTreeMenu($groupID);
  63. $this->view->recTotal = count($this->getMenuItems($this->view->treeMenu));
  64. $this->view->charts = $charts;
  65. $this->view->dimensionID = $dimensionID;
  66. $this->view->groupID = $groupID;
  67. $this->display();
  68. }
  69. /**
  70. * 获取筛选器表单。
  71. * Ajax get filter form html.
  72. *
  73. * @access public
  74. * @return string
  75. */
  76. public function ajaxGetFilterForm()
  77. {
  78. $fieldList = $this->post->fieldList;
  79. $filters = $this->post->filters;
  80. $fieldSettings = $this->post->fieldSettings;
  81. $langs = $this->post->langs;
  82. $sql = $this->post->sql;
  83. $clientLang = $this->app->getClientLang();
  84. $verifyResult = $this->loadModel('dataview')->verifySqlWithModify($sql);
  85. if($verifyResult !== true) return $this->send($verifyResult);
  86. $fieldPairs = array();
  87. foreach($fieldList as $field => $fieldName)
  88. {
  89. $fieldObject = $fieldSettings[$field]['object'];
  90. $relatedField = $fieldSettings[$field]['field'];
  91. $this->app->loadLang($fieldObject);
  92. $fieldPairs[$field] = isset($this->lang->$fieldObject->$relatedField) ? $this->lang->$fieldObject->$relatedField : $field;
  93. if(!isset($langs[$field])) continue;
  94. if(!empty($langs[$field][$clientLang])) $fieldPairs[$field] = $langs[$field][$clientLang];
  95. }
  96. $htmls = array();
  97. foreach($filters as $filter)
  98. {
  99. $field = $filter['field'];
  100. $type = $filter['type'];
  101. $default = isset($filter['default']) ? $filter['default'] : '';
  102. $saveAs = isset($filter['saveAs']) ? $filter['saveAs'] : '';
  103. $saveAsClass = $type == 'select' ? '' : 'hidden'; // 只有是选择的时候,才展示显示为
  104. $options = array();
  105. if($type == 'select')
  106. {
  107. $fieldSetting = $fieldSettings[$field];
  108. $options = $this->chart->getSysOptions(zget($fieldSetting, 'type', ''), zget($fieldSetting, 'object', ''), zget($fieldSetting, 'field', ''), $sql, zget($filter, 'saveAs', ''));
  109. }
  110. $filterHtml = array();
  111. /* field html */
  112. $filterHtml['field'] = html::select('field', $fieldPairs, $field, "class='form-control picker-select' onchange='initFilterForm(this, this.value)'");
  113. $filterHtml['saveAs'] = html::select('saveAs', array('' => '') + $fieldPairs, $saveAs, "class='form-control picker-select' onchange='changeSaveAs(this, this.value)'");
  114. $filterHtml['saveAsClass'] = $saveAsClass;
  115. /* default html */
  116. $filterHtml['default'] = '';
  117. if($type == 'input') $filterHtml['default'] .= html::input('default', $default, "class='form-control' onchange='changeDefault(this,this.value)'");
  118. if($type == 'date' or $type == 'datetime')
  119. {
  120. if(empty($default)) $default = array('begin' => '', 'end' => '');
  121. $class = $type == 'date' ? 'form-date' : 'form-datetime';
  122. $filterHtml['default'] .= '<div class="input-group">';
  123. $filterHtml['default'] .= html::input('default[begin]', $default['begin'], "class='form-control $class default-begin' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this,this.value)'");
  124. $filterHtml['default'] .= "<span class='input-group-addon fix-border borderBox' style='border-radius: 0px;'>{$this->lang->chart->colon}</span>";
  125. $filterHtml['default'] .= html::input('default[end]', $default['end'], "class='form-control $class default-end' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this,this.value)'");
  126. $filterHtml['default'] .= '</div>';
  127. }
  128. if($type == 'select') $filterHtml['default'] = html::select('default[]', $options, $default, "class='form-control picker-select' onchange='changeDefault(this,this.value)' multiple");
  129. if($type == 'condition')
  130. {
  131. $operator = isset($filter['operator']) ? $filter['operator'] : '';
  132. $value = isset($filter['value']) ? $filter['value'] : '';
  133. $hidden = strpos($operator, 'NULL') !== false ? 'hidden' : '';
  134. $filterHtml['default'] = "<div class='conditionGroup' style='display:flex'>";
  135. $filterHtml['default'] .= html::select('operator', $this->config->bi->conditionList, $operator, "class='form-control picker-select' onchange='changeCondition(this,this.value)'");
  136. $filterHtml['default'] .= html::input('value', $value, "class='form-control $hidden' onchange='changeConditionValue(this,this.value)'");
  137. $filterHtml['default'] .= "<div/>";
  138. }
  139. /* type html */
  140. $filterHtml['type'] = html::select('type', $this->lang->chart->fieldTypeList, $type, "class='form-control picker-select' onchange='changeType(this, this.value)'");
  141. /* filter item html */
  142. $filterHtml['item'] = '';
  143. if($type == 'input') $filterHtml['item'] .= html::input('default', $default, "class='form-control'");
  144. if($type == 'date' or $type == 'datetime')
  145. {
  146. if(empty($default)) $default = array('begin' => '', 'end' => '');
  147. $class = $type == 'date' ? 'form-date' : 'form-datetime';
  148. $filterHtml['item'] .= '<div class="input-group">';
  149. $filterHtml['item'] .= "<input type='text' name='default[begin]' id='default[begin]' value='{$default['begin']}' class='form-control $class default-begin' autocomplete='off' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this, this.value)'>";
  150. $filterHtml['item'] .= '<span class="input-group-addon fix-border borderBox" style="border-radius: 0px;">' . $this->lang->chart->colon . '</span>';
  151. $filterHtml['item'] .= "<input type='text' name='default[end]' id='default[end]' value='{$default['end']}' class='form-control $class default-end' autocomplete='off' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this, this.value)'>";
  152. $filterHtml['item'] .= '</div>';
  153. }
  154. if($type == 'select') $filterHtml['item'] .= html::select('default', array('' => '') + $options, $default, "class='form-control picker-select' multiple");
  155. if($type == 'condition')
  156. {
  157. $operator = isset($filter['operator']) ? $filter['operator'] : '';
  158. $value = isset($filter['value']) ? $filter['value'] : '';
  159. $hidden = strpos($operator, 'NULL') !== false ? 'hidden' : '';
  160. $filterHtml['item'] = "<div class='conditionGroup' style='display:flex'>";
  161. $filterHtml['item'] .= html::select('operator', $this->config->bi->conditionList, $operator, "class='form-control picker-select' onchange='changeCondition(this,this.value, true)'");
  162. $filterHtml['item'] .= html::input('value', $value, "class='form-control $hidden'");
  163. $filterHtml['item'] .= "<div/>";
  164. }
  165. $htmls[] = $filterHtml;
  166. }
  167. echo json_encode($htmls);
  168. }
  169. /**
  170. * 获取图表。
  171. * Ajax get chart.
  172. *
  173. * @access public
  174. * @return void
  175. */
  176. public function ajaxGetChart()
  177. {
  178. $post = fixer::input('post')->skipSpecial('settings,filters,sql,langs')->get();
  179. $settings = current($post->settings);
  180. $type = $settings['type'];
  181. $filters = isset($_POST['searchFilters']) ? $_POST['searchFilters'] : (isset($_POST['filters']) ? $post->filters : array());
  182. $filterFormat = $this->chart->getFilterFormat($filters);
  183. $sql = str_replace(';', '', "$post->sql");
  184. $fields = $post->fieldSettings;
  185. $langs = !empty($post->langs) ? $post->langs : array();
  186. if(is_string($langs)) $langs = json_decode($langs, true);
  187. switch($type)
  188. {
  189. case 'line':
  190. $data = $this->chart->genLineChart($fields, $settings, $sql, $filterFormat, $langs);
  191. break;
  192. case 'cluBarX':
  193. $data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, '', $langs);
  194. break;
  195. case 'cluBarY':
  196. $data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, '', $langs);
  197. break;
  198. case 'pie':
  199. $data = $this->chart->genPie($fields, $settings, $sql, $filterFormat);
  200. break;
  201. case 'radar':
  202. $data = $this->chart->genRadar($fields, $settings, $sql, $filterFormat, $langs);
  203. break;
  204. case 'stackedBar':
  205. $data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, 'total', $langs);
  206. break;
  207. case 'stackedBarY':
  208. $data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, 'total', $langs);
  209. break;
  210. case 'waterpolo':
  211. $data = $this->chart->genWaterpolo($settings, $sql, $filterFormat);
  212. break;
  213. }
  214. // 对于能进行旋转的图表,判断有没有设置旋转
  215. if(in_array($type, $this->config->chart->canLabelRotate))
  216. {
  217. if(isset($settings['rotateX']) and $settings['rotateX'] == 'use') $data['xAxis']['axisLabel'] = array('rotate' => 30);
  218. if(isset($settings['rotateY']) and $settings['rotateY'] == 'use') $data['yAxis']['axisLabel'] = array('rotate' => 30);
  219. }
  220. echo json_encode($data);
  221. }
  222. }