block_evaluation_graph.class.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use CpChart\Cache as pCache;
  4. use CpChart\Data as pData;
  5. use CpChart\Image as pImage;
  6. /**
  7. * Class BlockEvaluationGraph
  8. * This class is used like controller for this evaluations graph block plugin,
  9. * the class name must be registered inside path.info file
  10. * (e.g: controller = "BlockEvaluationGraph"),
  11. * so dashboard controller will be instantiate it.
  12. *
  13. * This file is part of evaluation graph block plugin for dashboard,
  14. * it should be required inside dashboard controller for showing it
  15. * into dashboard interface from platform
  16. *
  17. * @package chamilo.dashboard
  18. *
  19. * @author Christian Fasanando
  20. */
  21. class BlockEvaluationGraph extends Block
  22. {
  23. private $user_id;
  24. private $courses;
  25. private $sessions;
  26. private $permission = [DRH, SESSIONADMIN];
  27. /**
  28. * Constructor.
  29. */
  30. public function __construct($user_id)
  31. {
  32. $this->path = 'block_evaluation_graph';
  33. $this->user_id = $user_id;
  34. $this->bg_width = 450;
  35. $this->bg_height = 350;
  36. if ($this->is_block_visible_for_user($user_id)) {
  37. if (!api_is_session_admin()) {
  38. $this->courses = CourseManager::get_courses_followed_by_drh($user_id);
  39. }
  40. $this->sessions = SessionManager::get_sessions_followed_by_drh($user_id);
  41. }
  42. }
  43. /**
  44. * This method check if a user is allowed to see the block inside dashboard interface.
  45. *
  46. * @param int User id
  47. *
  48. * @return bool Is block visible for user
  49. */
  50. public function is_block_visible_for_user($user_id)
  51. {
  52. $user_info = api_get_user_info($user_id);
  53. $user_status = $user_info['status'];
  54. $is_block_visible_for_user = false;
  55. if (UserManager::is_admin($user_id) || in_array($user_status, $this->permission)) {
  56. $is_block_visible_for_user = true;
  57. }
  58. return $is_block_visible_for_user;
  59. }
  60. /**
  61. * This method return content html containing
  62. * information about sessions and its position for showing it inside dashboard interface
  63. * it's important to use the name 'get_block' for beeing used from dashboard controller.
  64. *
  65. * @return array column and content html
  66. */
  67. public function get_block()
  68. {
  69. $column = 1;
  70. $data = [];
  71. $evaluations_base_courses_graph = $this->get_evaluations_base_courses_graph();
  72. $evaluations_courses_in_sessions_graph = $this->get_evaluations_courses_in_sessions_graph();
  73. $html = '';
  74. if (empty($evaluations_base_courses_graph) && empty($evaluations_courses_in_sessions_graph)) {
  75. $html .= '<p>'.api_convert_encoding(get_lang('Graphic not available'), 'UTF-8').'</p>';
  76. } else {
  77. // display evaluations base courses graph
  78. if (!empty($evaluations_base_courses_graph)) {
  79. foreach ($evaluations_base_courses_graph as $course_code => $img_html) {
  80. $html .= '<div><strong>'.$course_code.'</strong></div>';
  81. $html .= $img_html;
  82. }
  83. }
  84. // display evaluations base courses graph
  85. if (!empty($evaluations_courses_in_sessions_graph)) {
  86. foreach ($evaluations_courses_in_sessions_graph as $session_id => $courses) {
  87. $session_name = api_get_session_name($session_id);
  88. $html .= '<div><strong>'.$session_name.':'.get_lang('Evaluations').'</strong></div>';
  89. foreach ($courses as $course_code => $img_html) {
  90. $html .= '<div><strong>'.$course_code.'</strong></div>';
  91. $html .= $img_html;
  92. }
  93. }
  94. }
  95. }
  96. $html = $this->getBlockCard(
  97. get_lang('Graph of evaluations'),
  98. $html
  99. );
  100. $data['column'] = $column;
  101. $data['content_html'] = $html;
  102. return $data;
  103. }
  104. /**
  105. * This method return a graph containing informations about evaluations
  106. * inside base courses, it's used inside get_block method for showing
  107. * it inside dashboard interface.
  108. *
  109. * @return string img html
  110. */
  111. public function get_evaluations_base_courses_graph()
  112. {
  113. $graphs = [];
  114. if (!empty($this->courses)) {
  115. $courses_code = array_keys($this->courses);
  116. foreach ($courses_code as $course_code) {
  117. $cats = Category::load(
  118. null,
  119. null,
  120. $course_code,
  121. null,
  122. null,
  123. null,
  124. false
  125. );
  126. if (isset($cats) && isset($cats[0])) {
  127. $alleval = $cats[0]->get_evaluations(null, true, $course_code);
  128. $alllinks = $cats[0]->get_links(null, true);
  129. $users = GradebookUtils::get_all_users($alleval, $alllinks);
  130. $datagen = new FlatViewDataGenerator($users, $alleval, $alllinks);
  131. $evaluation_sumary = $datagen->getEvaluationSummaryResults();
  132. if (!empty($evaluation_sumary)) {
  133. $items = array_keys($evaluation_sumary);
  134. $max = $min = $avg = [];
  135. foreach ($evaluation_sumary as $evaluation) {
  136. $max[] = $evaluation['max'];
  137. $min[] = !empty($evaluation['min']) ? $evaluation['min'] : 0;
  138. $avg[] = $evaluation['avg'];
  139. }
  140. // Dataset definition
  141. $dataSet = new pData();
  142. $dataSet->addPoints($min, 'Serie3');
  143. $dataSet->addPoints($avg, 'Serie2');
  144. $dataSet->addPoints($max, 'Serie1');
  145. $dataSet->addPoints($items, 'Labels');
  146. $dataSet->setSerieDescription('Serie1', get_lang('Maximum'));
  147. $dataSet->setSerieDescription('Serie2', get_lang('Average'));
  148. $dataSet->setSerieDescription('Serie3', get_lang('Minimum'));
  149. $dataSet->setAbscissa('Labels');
  150. $dataSet->setAbscissaName(get_lang('Assessment'));
  151. $dataSet->normalize(100, '%');
  152. $dataSet->loadPalette(api_get_path(SYS_CODE_PATH).'palettes/pchart/default.color', true);
  153. // Cache definition
  154. $cachePath = api_get_path(SYS_ARCHIVE_PATH);
  155. $myCache = new pCache(['CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)]);
  156. $chartHash = $myCache->getHash($dataSet);
  157. if ($myCache->isInCache($chartHash)) {
  158. $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
  159. $myCache->saveFromCache($chartHash, $imgPath);
  160. $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
  161. } else {
  162. /* Create the pChart object */
  163. $widthSize = $this->bg_width;
  164. $heightSize = $this->bg_height;
  165. $fontSize = 8;
  166. $angle = 50;
  167. $myPicture = new pImage($widthSize, $heightSize, $dataSet);
  168. /* Turn of Antialiasing */
  169. $myPicture->Antialias = false;
  170. /* Add a border to the picture */
  171. $myPicture->drawRectangle(
  172. 0,
  173. 0,
  174. $widthSize - 1,
  175. $heightSize - 1,
  176. [
  177. 'R' => 0,
  178. 'G' => 0,
  179. 'B' => 0,
  180. ]
  181. );
  182. /* Set the default font */
  183. $myPicture->setFontProperties(
  184. [
  185. 'FontName' => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
  186. 'FontSize' => 10,
  187. ]
  188. );
  189. /* Do NOT Write the chart title */
  190. /* Define the chart area */
  191. $myPicture->setGraphArea(
  192. 50,
  193. 30,
  194. $widthSize - 20,
  195. $heightSize - 100
  196. );
  197. /* Draw the scale */
  198. $scaleSettings = [
  199. 'GridR' => 200,
  200. 'GridG' => 200,
  201. 'GridB' => 200,
  202. 'DrawSubTicks' => true,
  203. 'CycleBackground' => true,
  204. 'Mode' => SCALE_MODE_MANUAL,
  205. 'ManualScale' => [
  206. '0' => [
  207. 'Min' => 0,
  208. 'Max' => 100,
  209. ],
  210. ],
  211. 'LabelRotation' => $angle,
  212. ];
  213. $myPicture->drawScale($scaleSettings);
  214. /* Turn on shadow computing */
  215. $myPicture->setShadow(
  216. true,
  217. [
  218. 'X' => 1,
  219. 'Y' => 1,
  220. 'R' => 0,
  221. 'G' => 0,
  222. 'B' => 0,
  223. 'Alpha' => 10,
  224. ]
  225. );
  226. /* Draw the chart */
  227. $myPicture->setShadow(
  228. true,
  229. [
  230. 'X' => 1,
  231. 'Y' => 1,
  232. 'R' => 0,
  233. 'G' => 0,
  234. 'B' => 0,
  235. 'Alpha' => 10,
  236. ]
  237. );
  238. $settings = [
  239. 'DisplayValues' => true,
  240. 'DisplaySize' => $fontSize,
  241. 'DisplayR' => 0,
  242. 'DisplayG' => 0,
  243. 'DisplayB' => 0,
  244. 'DisplayOrientation' => ORIENTATION_HORIZONTAL,
  245. 'Gradient' => false,
  246. 'Surrounding' => 30,
  247. 'InnerSurrounding' => 25,
  248. ];
  249. $myPicture->drawStackedBarChart($settings);
  250. $legendSettings = [
  251. 'Mode' => LEGEND_HORIZONTAL,
  252. 'Style' => LEGEND_NOBORDER,
  253. ];
  254. $myPicture->drawLegend($widthSize / 2, 15, $legendSettings);
  255. /* Write and save into cache */
  256. $myCache->writeToCache($chartHash, $myPicture);
  257. $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
  258. $myCache->saveFromCache($chartHash, $imgPath);
  259. $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
  260. }
  261. if (!empty($imgPath)) {
  262. $courses_graph[$course_code] = '<img src="'.$imgPath.'">';
  263. }
  264. }
  265. }
  266. } // end for
  267. }
  268. return $graphs;
  269. }
  270. /**
  271. * This method return a graph containing information about evaluations
  272. * inside courses in sessions, it's used inside get_block method for
  273. * showing it inside dashboard interface.
  274. *
  275. * @return string img html
  276. */
  277. public function get_evaluations_courses_in_sessions_graph()
  278. {
  279. $graphs = [];
  280. if (!empty($this->sessions)) {
  281. $session_ids = array_keys($this->sessions);
  282. foreach ($session_ids as $session_id) {
  283. $courses_code = array_keys(Tracking::get_courses_list_from_session($session_id));
  284. $courses_graph = [];
  285. foreach ($courses_code as $course_code) {
  286. $cats = Category::load(null, null, $course_code, null, null, $session_id);
  287. if (isset($cats) && isset($cats[0])) {
  288. $alleval = $cats[0]->get_evaluations(null, true, $course_code);
  289. $alllinks = $cats[0]->get_links(null, true);
  290. $users = GradebookUtils::get_all_users($alleval, $alllinks);
  291. $datagen = new FlatViewDataGenerator($users, $alleval, $alllinks);
  292. $evaluation_sumary = $datagen->getEvaluationSummaryResults();
  293. if (!empty($evaluation_sumary)) {
  294. $items = array_keys($evaluation_sumary);
  295. $max = $min = $avg = [];
  296. foreach ($evaluation_sumary as $evaluation) {
  297. $max[] = $evaluation['max'];
  298. $min[] = $evaluation['min'];
  299. $avg[] = $evaluation['avg'];
  300. }
  301. // Dataset definition
  302. $dataSet = new pData();
  303. $dataSet->addPoints($min, 'Serie3');
  304. $dataSet->addPoints($avg, 'Serie2');
  305. $dataSet->addPoints($max, 'Serie1');
  306. $dataSet->addPoints($items, 'Labels');
  307. $dataSet->setSerieDescription('Serie1', get_lang('Maximum'));
  308. $dataSet->setSerieDescription('Serie2', get_lang('Avg'));
  309. $dataSet->setSerieDescription('Serie3', get_lang('Minimum'));
  310. $dataSet->setAbscissa('Labels');
  311. $dataSet->setAbscissaName(get_lang('Assessment'));
  312. $dataSet->normalize(100, '%');
  313. $dataSet->loadPalette(api_get_path(SYS_CODE_PATH).'palettes/pchart/default.color', true);
  314. // Cache definition
  315. $cachePath = api_get_path(SYS_ARCHIVE_PATH);
  316. $myCache = new pCache(
  317. [
  318. 'CacheFolder' => substr(
  319. $cachePath,
  320. 0,
  321. strlen($cachePath) - 1
  322. ),
  323. ]
  324. );
  325. $chartHash = $myCache->getHash($dataSet);
  326. if ($myCache->isInCache($chartHash)) {
  327. $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
  328. $myCache->saveFromCache($chartHash, $imgPath);
  329. $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
  330. } else {
  331. /* Create the pChart object */
  332. $widthSize = $this->bg_width;
  333. $heightSize = $this->bg_height;
  334. $fontSize = 8;
  335. $angle = 50;
  336. $myPicture = new pImage($widthSize, $heightSize, $dataSet);
  337. /* Turn of Antialiasing */
  338. $myPicture->Antialias = false;
  339. /* Add a border to the picture */
  340. $myPicture->drawRectangle(
  341. 0,
  342. 0,
  343. $widthSize - 1,
  344. $heightSize - 1,
  345. [
  346. 'R' => 0,
  347. 'G' => 0,
  348. 'B' => 0,
  349. ]
  350. );
  351. /* Set the default font */
  352. $myPicture->setFontProperties(
  353. [
  354. 'FontName' => api_get_path(SYS_FONTS_PATH).'opensans/OpenSans-Regular.ttf',
  355. 'FontSize' => 10,
  356. ]
  357. );
  358. /* Do NOT Write the chart title */
  359. /* Define the chart area */
  360. $myPicture->setGraphArea(50, 30, $widthSize - 20, $heightSize - 100);
  361. /* Draw the scale */
  362. $scaleSettings = [
  363. 'GridR' => 200,
  364. 'GridG' => 200,
  365. 'GridB' => 200,
  366. 'DrawSubTicks' => true,
  367. 'CycleBackground' => true,
  368. 'Mode' => SCALE_MODE_MANUAL,
  369. 'ManualScale' => [
  370. '0' => [
  371. 'Min' => 0,
  372. 'Max' => 100,
  373. ],
  374. ],
  375. 'LabelRotation' => $angle,
  376. ];
  377. $myPicture->drawScale($scaleSettings);
  378. /* Turn on shadow computing */
  379. $myPicture->setShadow(
  380. true,
  381. [
  382. 'X' => 1,
  383. 'Y' => 1,
  384. 'R' => 0,
  385. 'G' => 0,
  386. 'B' => 0,
  387. 'Alpha' => 10,
  388. ]
  389. );
  390. /* Draw the chart */
  391. $myPicture->setShadow(
  392. true,
  393. [
  394. 'X' => 1,
  395. 'Y' => 1,
  396. 'R' => 0,
  397. 'G' => 0,
  398. 'B' => 0,
  399. 'Alpha' => 10,
  400. ]
  401. );
  402. $settings = [
  403. 'DisplayValues' => true,
  404. 'DisplaySize' => $fontSize,
  405. 'DisplayR' => 0,
  406. 'DisplayG' => 0,
  407. 'DisplayB' => 0,
  408. 'DisplayOrientation' => ORIENTATION_HORIZONTAL,
  409. 'Gradient' => false,
  410. 'Surrounding' => 30,
  411. 'InnerSurrounding' => 25,
  412. ];
  413. $myPicture->drawStackedBarChart($settings);
  414. $legendSettings = [
  415. 'Mode' => LEGEND_HORIZONTAL,
  416. 'Style' => LEGEND_NOBORDER,
  417. ];
  418. $myPicture->drawLegend($widthSize / 2, 15, $legendSettings);
  419. /* Write and save into cache */
  420. $myCache->writeToCache($chartHash, $myPicture);
  421. $imgPath = api_get_path(SYS_ARCHIVE_PATH).$chartHash;
  422. $myCache->saveFromCache($chartHash, $imgPath);
  423. $imgPath = api_get_path(WEB_ARCHIVE_PATH).$chartHash;
  424. }
  425. if (!empty($imgPath)) {
  426. $courses_graph[$course_code] = '<img src="'.$imgPath.'">';
  427. }
  428. }
  429. }
  430. }
  431. if (!empty($courses_graph)) {
  432. $graphs[$session_id] = $courses_graph;
  433. }
  434. }
  435. }
  436. return $graphs;
  437. }
  438. }