Advertisement
sixfootjames

Graph Generator

Jan 25th, 2018
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.38 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * @file
  5. * Custom graphing functionality for the EconRSA website
  6. *
  7. */
  8.  
  9. // Where we store our graph source files
  10. define('ECONRSA_GRAPHS_FILE_PATH', 'sites/default/files/private/graphs');
  11. define('ECONRSA_GRAPHS_INTERVAL_MONTHLY', 30 * 24 * 3600 * 1000);
  12. define('ECONRSA_GRAPHS_INTERVAL_QUARTERLY', 3 * 30 * 24 * 3600 * 1000);
  13. define('ECONRSA_GRAPHS_INTERVAL_YEARLY', 12 * 30 * 24 * 3600 * 1000);
  14. define('ECONRSA_GRAPHS_THRESHOLD_DEFAULT', 2);
  15. define('ECONRSA_GRAPHS_PARAMETERS_DIR', 'parameters');
  16. define('ECONRSA_GRAPHS_MPV_BASE_PATH', 'ersagraphs/mpv');
  17.  
  18. /**
  19. * Implementation of hook_perm()
  20. */
  21. function econrsa_graphs_perm() {
  22. return array('view ersa graphs');
  23. }
  24. /**
  25. * Implementation of hook_permission().
  26. */
  27. function econrsa_graphs_permission() {
  28. return array(
  29. 'access ersa graphs' => array(
  30. 'title' => t('Administer ERSA Graphs'),
  31. 'description' => t('Access the ERSA Graphs admin section.'),
  32. ),
  33. 'view ersa graphs' => array(
  34. 'title' => t('View ERSA graphs'),
  35. 'description' => t('View any of the ERSA graphs.'),
  36. ),
  37. );
  38. }
  39.  
  40. /**
  41. * Implementation of hook_menu()
  42. */
  43. function econrsa_graphs_menu() {
  44. $items[ECONRSA_GRAPHS_MPV_BASE_PATH . '/%/%/view'] = array(
  45. 'title' => 'Macroeconomic Volatility Project Graphs',
  46. 'page callback' => 'econrsa_graphs_show_graph',
  47. 'page arguments' => array(2, 3),
  48. 'access arguments' => array('view ersa graphs'),
  49. );
  50. $items[ECONRSA_GRAPHS_MPV_BASE_PATH . '/list'] = array(
  51. 'title' => 'Macroeconomic Volatility Project Graphs (listing)',
  52. 'page callback' => 'econrsa_graphs_display_menu',
  53. 'access arguments' => array('view ersa graphs'),
  54. );
  55. $items[ECONRSA_GRAPHS_MPV_BASE_PATH . '/about'] = array(
  56. 'title' => 'Macroeconomic Volatility Project',
  57. 'page callback' => 'econrsa_graphs_display_about',
  58. 'access arguments' => array('access content'),
  59. );
  60. return $items;
  61. }
  62.  
  63. /**
  64. * Function to display a listing of graphs
  65. */
  66. function econrsa_graphs_display_menu() {
  67. $description = "<div class='econrsa-graphs-description'>";
  68. $description .= t('Please click on any of the following links to go to the respective pressure variable graphs. The graphs will allow users to select the desired threshold levels. The pressure variable graphs are further explained briefly in the page. Users will be able see component graphs (weighted) in the same page to further elaborate their effects on the pressure variable.');
  69. $description .= "</div>";
  70. $graphs = econrsa_graphs_load_graph_filenames();
  71. $list_items = array();
  72. foreach($graphs as $graph) {
  73. $list_items[] = l($graph['title'], 'ersagraphs/mpv/' . $graph['filename'] . '/' . $graph['type'] . '/view');
  74. }
  75. $output = array(
  76. 'graphs_menu' => array(
  77. '#type' => 'markup',
  78. '#markup' => $description . theme('item_list', array('items' => $list_items)),
  79. ),
  80. );
  81. return $output;
  82. }
  83.  
  84. /**
  85. * Display information about the graph feature.
  86. */
  87. function econrsa_graphs_display_about() {
  88. global $user;
  89. if(user_is_logged_in()) {
  90. if (user_access('view ersa graphs')) {
  91. $link = l(t('Access the graphs here.'), ECONRSA_GRAPHS_MPV_BASE_PATH . '/list');
  92. }
  93. else {
  94. $link = t('Unfortunately, your user role does not permit you to access the graphs.');
  95. }
  96. }
  97. else {
  98. $message = t('Please log in to access the graphs.');
  99. $link = l($message, 'user/login', array('query' => array('destination' => ECONRSA_GRAPHS_MPV_BASE_PATH . '/list'), 'external' => FALSE));
  100. }
  101. $description_text = t('The pressure indicators aim at developing an early
  102. warning mechanism on the macroeconomic conditions of
  103. various types of South Africa. The current indicators
  104. use historical data to analyze the South African economy
  105. from seven perspectives. The current calculations and
  106. graph aim to point out years with abnormal deviations
  107. for the economic indicators which would theoretically
  108. suggest pressure scenarios. This project is a work in
  109. progress and aims to give users a look into historical
  110. macroeconomic deviations, especially the years when
  111. South Africa experienced abnormal shocks. For current
  112. use, these indexes could assist users to take a deeper
  113. look at the historical development of the South African
  114. economy, and analyze variables within each indicator
  115. that led to these shock moments. A key feature of the
  116. graphics is the facility to break down each indicator
  117. into its sub-components which allows users to study in
  118. more detail the composition of macroeconomic pressure.');
  119.  
  120. $content = "<p>$description_text</p>";
  121. $content .= '<p>' . $link . '</p>';
  122. $contact = l('send us an email', 'mailto:Yoemna.Mosaval@econrsa.org');
  123. $content .= spamspan(t('If you do not have a user account and you require access to the graphs, please !contact_us.', array('!contact_us' => $contact)));
  124. $output = array(
  125. 'econrsa_graphs_about' => array(
  126. '#type' => 'markup',
  127. '#markup' => $content,
  128. ),
  129. );
  130. return $output;
  131. }
  132.  
  133. /**
  134. * Return a list of all graphs we want to display
  135. */
  136. function econrsa_graphs_load_graph_filenames() {
  137. $graphs = array(
  138.  
  139. array('title' => t('Bank Pressure Indicator 1 Combined MPV (excluding non-performing loans)'),
  140. 'filename' => 'bank-pressure-indicator-1-without-np-combined-values',
  141. 'type' => 'combined',
  142. ),
  143. array('title' => t('Bank Pressure Indicator 1 Combined MPV (including non-performing loans)'),
  144. 'filename' => 'bank-pressure-indicator-1-with-np-combined-values',
  145. 'type' => 'combined',
  146. ),
  147. array('title' => t('Bank Pressure Indicator 2 Combined MPV (excluding non-performing loans)'),
  148. 'filename' => 'bank-pressure-indicator-2-without-np-combined-values',
  149. 'type' => 'combined',
  150. ),
  151. array('title' => t('Bank Pressure Indicator 2 Combined MPV (including non-performing loans)'),
  152. 'filename' => 'bank-pressure-indicator-2-with-np-combined-values',
  153. 'type' => 'combined',
  154. ),
  155. array('title' => t('Capital Account Pressure Indicator Combined MPV'),
  156. 'filename' => 'capital-account-pressure-indicator-combined-values',
  157. 'type' => 'combined',
  158. ),
  159. array('title' => t('Currency Combined MPV'),
  160. 'filename' => 'currency-combined-values',
  161. 'type' => 'combined',
  162. ),
  163. array('title' => t('Current Pressure Indicator Without Gold Combined MPV'),
  164. 'filename' => 'current-pressure-indicator-without-gold-values',
  165. 'type' => 'combined',
  166. ),
  167. array('title' => t('Current Pressure Indicator With Gold Combined MPV'),
  168. 'filename' => 'current-pressure-indicator-with-gold-values',
  169. 'type' => 'combined',
  170. ),
  171. array('title' => t('Debt Pressure Indicator Combined MPV'),
  172. 'filename' => 'debt-pressure-indicator-combined-values',
  173. 'type' => 'combined',
  174. ),
  175. array('title' => t('Fiscal Policy Pressure Indicator Breakdown Model Combined MPV'),
  176. 'filename' => 'fiscal-policy-pressure-indicator-breakdown-values',
  177. 'type' => 'combined',
  178. ),
  179. array('title' => t('Fiscal Policy Pressure Indicator Basic Model Combined MPV'),
  180. 'filename' => 'fiscal-policy-pressure-indicator-basic-values',
  181. 'type' => 'combined',
  182. ),
  183. array('title' => t('Macroeconomic Pressure Combined MPV'),
  184. 'filename' => 'macroeconomic-pressure-combined-values',
  185. 'type' => 'combined',
  186. ),
  187. );
  188. return $graphs;
  189. }
  190.  
  191. /**
  192. * Function to display Market Pressure Variable (MPV) graphs
  193. * $id string filname of the excel file without the type, e.g. mpv-graph-1
  194. */
  195. function econrsa_graphs_show_graph($id, $type) {
  196. $output = array();
  197. $library = libraries_load('PHPExcel');
  198. if (!empty($library['loaded'])) {
  199. if ($charts = econrsa_graphs_load_graphs(check_plain($id), check_plain($type))) {
  200. //dpm($charts);
  201. drupal_add_js(array('econrsaGraphs' => array('charts' => $charts)), 'setting');
  202. $html = l(t('Back to the list of all MPV graphs'), ECONRSA_GRAPHS_MPV_BASE_PATH . '/list');
  203. $html .= $charts['mpv']['html'];
  204. // Setup the quicktabs for the spider and component graphs
  205. //dpm($charts['components']);
  206. $html .= econrsa_graphs_setup_tabs($charts['mpv'], $charts['spider'], $charts['components']);
  207. $output = array(
  208. 'graph_container' => array(
  209. '#type' => 'markup',
  210. '#markup' => $html,
  211. ),
  212. );
  213. }
  214. else {
  215. drupal_set_message(t("Graph @id could not be displayed.", array('@id' => $id)), 'error');
  216. }
  217. }
  218. else {
  219. drupal_set_message(t("Could not load PHPExcel library"), 'error');
  220. }
  221. $crumbs = array();
  222. $crumbs[] = l(t('Home'), '<front>');
  223. $crumbs[] = l(t('Market Pressure Variable Graphs'), 'ersagraphs/mpv/list');
  224. drupal_set_breadcrumb($crumbs);
  225. // We are currently using the graph title, so use a generic page title
  226. //drupal_set_title($options['page_title']);
  227. return $output;
  228. }
  229.  
  230.  
  231.  
  232.  
  233. /**
  234. * Loads the data for a set of graphs (could also just be one graph)
  235. *
  236. * @todo I want to actually set up a class for our graphs, but don't have time
  237. * right now
  238. *
  239. */
  240. function econrsa_graphs_load_graphs($id, $type) {
  241. // Load the parameters for the graph based on the id. Will then be available
  242. // in the $parameters variable
  243. //if (!is_null(module_load_include('inc', 'econrsa_graphs', ECONRSA_GRAPHS_PARAMETERS_DIR . '/' . $id))) {
  244. if (include_once( DRUPAL_ROOT . '/' . drupal_get_path('module', 'econrsa_graphs') . '/' . ECONRSA_GRAPHS_PARAMETERS_DIR . '/' . $id . '.inc')) {
  245.  
  246. $parameters['id'] = $id;
  247. $parameters['filename'] = $id . '.xlsx';
  248. $charts = array('page_title' => $parameters['title']);
  249.  
  250. $parameters = econrsa_graphs_load_excel($parameters);
  251. // $parameters now contains all the data we require from the excel spreadsheet
  252.  
  253. drupal_add_js(libraries_get_path('highcharts') . '/js/highcharts.js');
  254. drupal_add_js(libraries_get_path('highcharts') . '/js/modules/exporting.js');
  255. $start_time = $parameters['point_start_js_timestamp'];
  256.  
  257. switch($parameters['type']) {
  258. case 'combined':
  259. // We setup ALL graphs - combined mpv, components spider and individual components
  260. $parameters['series_title'] = t('Scaled MPV');
  261. // Load our javascript file for this type of graph
  262. drupal_add_js(drupal_get_path('module', 'econrsa_graphs') . '/js/single_mpv.js');
  263.  
  264. // Combined MPV
  265. $charts['mpv'] = econrsa_graphs_setup_mpv_linear($id, $parameters);
  266. //dpm($parameters);
  267. $charts['components'] = econrsa_graphs_setup_mpv_components($parameters);
  268. $charts['spider'] = econrsa_graphs_setup_mpv_spider($parameters);
  269. // For displaying the individual components in tabs
  270. //foreach($parameters['multiple_components'] as $key => $component) {
  271. // $charts['components'][$key] = econrsa_graphs_setup_mpv_component($key, $component, $parameters);
  272. //}
  273. break;
  274. }
  275. return $charts;
  276. }
  277. else {
  278. drupal_set_message(t('Could not load graph parameters file.'), 'error');
  279. }
  280. }
  281. /**
  282. * Read the excel file for the values we will use in graphs and or calculations
  283. *
  284. * @param array $parameters The specific graph options.
  285. *
  286. * @return array Updated parameters array containing the excel data ready for graphing
  287. */
  288. function econrsa_graphs_load_excel($parameters) {
  289. // When reading from sheets which include the calculations, we need to increase
  290. // the php script timeout limit - this means we really need to implement caching
  291. // otherwise the site will run out of memory
  292. set_time_limit(240);
  293. // Need to cache the data for each graph because it's only going to be updated
  294. // once every 3 month so no need to physically read it each time
  295.  
  296. // check file exists
  297. $graph_file = ECONRSA_GRAPHS_FILE_PATH . '/' . $parameters['filename'];
  298.  
  299. if (is_readable($graph_file)) {
  300. // Initialise the excel reader and fetch the sheet data
  301. try {
  302. $input_file_type = PHPExcel_IOFactory::identify($graph_file);
  303. $obj_reader = PHPExcel_IOFactory::createReader($input_file_type);
  304. $obj_reader->setReadDataOnly(TRUE);
  305. $obj_php_excel = $obj_reader->load($graph_file);
  306. } catch (Exception $e) {
  307. die('Error loading file "' . pathinfo($graph_file, PATHINFO_BASENAME)
  308. . '": ' . $e->getMessage());
  309. }
  310. // Get worksheet dimensions
  311. $sheet = $obj_php_excel->getSheet(0);
  312. // Read the Date when the workbook was last modified (as a PHP timestamp value)
  313. $modified_datestamp = $obj_php_excel->getProperties()->getModified();
  314. //Format the date and time using the standard PHP date() function
  315. $modified_date = date('l, d F Y',$modified_datestamp);
  316. $modified_time = date('g:i A', $modified_datestamp);
  317. $parameters['meta']['modified_date'] = $modified_date;
  318. $parameters['meta']['modified_time'] = $modified_time;
  319. $highest_row = $sheet->getHighestRow();
  320. $parameters['meta']['highest_row'] = $highest_row;
  321.  
  322. $parameters['components_headers'] = $sheet->rangeToArray($parameters['component_start_column'] . $parameters['header_row_number'] . ':' .
  323. $parameters['component_end_column'] . $parameters['header_row_number'], NULL, TRUE, FALSE);
  324. // Read the calculated, combined MPV
  325. $parameters['calculated_mpv_values'] = $sheet->rangeToArray($parameters['scaled_mpv_column'] . $parameters['data_starting_row_number'] . ':' .
  326. $parameters['scaled_mpv_column'] . $highest_row, NULL, TRUE, FALSE);
  327. // Clean up the arrays
  328. $parameters['components_headers'] = array_values($parameters['components_headers'][0]);
  329. // Read the date column, don't use rangeToArray because we want to modify in some cases
  330. for ($row = $parameters['data_starting_row_number']; $row <= $highest_row; $row++) {
  331. $date = $sheet->getCell($parameters['date_column'] . $row)->getValue();
  332. if ($parameters['date_type'] == 'excel_timestamp') {
  333. $date = PHPExcel_Shared_Date::ExcelToPHP($date) * 1000;
  334. }
  335. else {
  336. $date = (string) $date;
  337. }
  338. $parameters['date_values'][] = $date;
  339. }
  340.  
  341. // Set up the component checkboxes
  342. $parameters['html']['component_checkboxes'] = '<div id="component-checkboxes"><h3>Add or remove components</h3>';
  343. foreach($parameters['components_headers'] as $key=>$val) {
  344. $component_title = t(check_plain($val));
  345. $parameters['menu']['components'][] = l($component_title, ECONRSA_GRAPHS_MPV_BASE_PATH . '/' . $parameters['id'] . '/components/view');
  346. $parameters['html']['component_checkboxes'] .= "<input type='checkbox' class='component-checkbox' id='component-" . $key ."' name='component-" . $key ."' value='" . $key . "' checked>" . $component_title . "<br>";
  347. $parameters['multiple_components'][$key]['component_title'] = $component_title;
  348. }
  349.  
  350. $parameters['html']['component_checkboxes'] .= '</div>';
  351.  
  352. // Load the components used to generate the scaled MPV values, only
  353. // necessary if we are wanting to allow the user change the graph
  354. $parameters['components'] = $sheet->rangeToArray($parameters['component_start_column'] . $parameters['data_starting_row_number'] . ':' .
  355. $parameters['component_end_column'] . $highest_row, NULL, TRUE, FALSE);
  356. $highest_component_value = 0.0;
  357. $lowest_component_value = 0.0;
  358.  
  359. for ($row = 0; $row < count($parameters['date_values']); $row++) {
  360. // Get the series data for the single calculated mpv graph
  361. $value = round((float) $parameters['calculated_mpv_values'][$row][0], 2);
  362. $parameters['named_points'][] = array('name' => $parameters['date_values'][$row], 'y' => $value);
  363.  
  364. // Get the series data for each component cell in a row
  365. foreach($parameters['components'][$row] as $key => $cell_value) {
  366. // We need to store the lowest and highest value for setting a fixed scale on y
  367. $highest_component_value = ($cell_value > $highest_component_value ? $cell_value : $highest_component_value);
  368. $lowest_component_value = ($cell_value < $lowest_component_value ? $cell_value : $lowest_component_value);
  369. $component_value = round((float) $cell_value, 2);
  370. $parameters['multiple_components'][$key]['named_points'][] = array('name' => $parameters['date_values'][$row], 'y' => $component_value);
  371. }
  372. }
  373. $parameters['highest_component_value'] = $highest_component_value;
  374. $parameters['lowest_component_value'] = $lowest_component_value;
  375.  
  376. //dpm($parameters);
  377. }
  378. else {
  379. drupal_set_message(t("Failed to load graph data."), 'error');
  380. }
  381. return($parameters);
  382. }
  383.  
  384. if (!function_exists('stats_standard_deviation')) {
  385. /**
  386. * This user-land implementation follows the implementation quite strictly;
  387. * it does not attempt to improve the code or algorithm in any way. It will
  388. * raise a warning if you have fewer than 2 values in your array, just like
  389. * the extension does (although as an E_USER_WARNING, not E_WARNING).
  390. *
  391. * @param array $a
  392. * @param bool $sample [optional] Defaults to false
  393. * @return float|bool The standard deviation or false on error.
  394. */
  395. function stats_standard_deviation(array $a, $sample = false) {
  396. $n = count($a);
  397. if ($n === 0) {
  398. trigger_error("The array has zero elements", E_USER_WARNING);
  399. return false;
  400. }
  401. if ($sample && $n === 1) {
  402. trigger_error("The array has only 1 element", E_USER_WARNING);
  403. return false;
  404. }
  405. $mean = array_sum($a) / $n;
  406. $carry = 0.0;
  407. foreach ($a as $val) {
  408. $d = ((double) $val) - $mean;
  409. $carry += $d * $d;
  410. };
  411. if ($sample) {
  412. --$n;
  413. }
  414. return sqrt($carry / $n);
  415. }
  416. }
  417.  
  418. /**
  419. * Given an array of MPV components, calculate the sum of each row and store
  420. * these in an array for reference.
  421. *
  422. * @param array $components Indexed array (indexed on row number) containing
  423. * each of the mpv components taken from the excel spreadsheet
  424. * @param array $exclude List of columns (keys) to exclude from the sum
  425. *
  426. * @return array $mpv_summed_values
  427. */
  428. function econrsa_graphs_calculate_mpv_sum($components, $exclude = array()) {
  429. $mpv_summed_values = array();
  430. foreach($components as $row) {
  431. // Remove the excluded column(s)
  432. if (!empty($exclude)) {
  433. foreach($exclude as $key) {
  434. unset($row[$key]);
  435. }
  436. }
  437. $mpv_summed_values[] = array_sum($row);
  438. }
  439. return $mpv_summed_values;
  440. }
  441.  
  442. /**
  443. * Given an array of MPV values, calculate the scaled mpv values.
  444. *
  445. * @param array $values Indexed array (indexed on row number) containing
  446. * each of the mpv components taken from the excel spreadsheet
  447. *
  448. * @return array $mpv_summed_values
  449. */
  450. function econrsa_graphs_calculate_scaled_mpv($values, $exclude = array()) {
  451. $mpv_summed_values = econrsa_graphs_calculate_mpv_sum($values, $exclude);
  452. $mpv_ave = econrsa_graphs_calculate_mpv_average($mpv_summed_values);
  453. $std_dev = econrsa_graphs_calculate_std_deviation($mpv_summed_values);
  454. $scaled_mpvs = array();
  455. foreach($mpv_summed_values as $value) {
  456. $scaled_mpvs[] = ($value - $mpv_ave) / $std_dev;
  457. }
  458. return $scaled_mpvs;
  459. }
  460.  
  461. /**
  462. * Given an array of summed MPV values (from components), calculate the average value.
  463. *
  464. * @param array $mpv_summed_values The array of summed MPV values
  465. *
  466. * @return float The average of all values the array
  467. */
  468. function econrsa_graphs_calculate_mpv_average($mpv_summed_values) {
  469. return (array_sum($mpv_summed_values) / count($mpv_summed_values));
  470. }
  471.  
  472. /**
  473. * Given an array of summed MPV values (from components), calculate the standard deviation.
  474. *
  475. * @param array $mpv_summed_values The array of summed MPV values
  476. *
  477. * @return float The standard deviation
  478. */
  479. function econrsa_graphs_calculate_std_deviation($mpv_summed_values) {
  480. return stats_standard_deviation($mpv_summed_values);
  481. }
  482.  
  483. /**
  484. * Add the javascript and html for displaying a single linear mpv component graph
  485. *
  486. */
  487. function econrsa_graphs_setup_mpv_component($key, $component, $parameters) {
  488.  
  489. // Prepare the highcharts settings for this type of graph
  490. // Graph configuration
  491. $highcharts_settings = array(
  492. 'chart' => array(
  493. 'renderTo' => 'chart-component-' . $key,
  494. 'zoomType' => 'xy',
  495. ),
  496. 'xAxis' => array(
  497. 'type' => 'datetime',
  498. ),
  499. 'yAxis' => array(
  500. 'title' => array('text' => 'Value'),
  501. 'max' => $parameters['highest_component_value'],
  502. 'min' => $parameters['lowest_component_value'],
  503. ),
  504. 'title' => array(
  505. 'text' => $component['component_title'],
  506. 'style' => array('color' => '#000000', 'fontSize' => '14px', 'fontWeight' => 'bold'),
  507. ),
  508. 'subtitle' => array(
  509. 'text' => t('Data last updated: @modified_date at @modified_time.',
  510. array('@modified_date' => $parameters['meta']['modified_date'], '@modified_time' => $parameters['meta']['modified_time'])),
  511. 'align' => 'right',
  512. 'verticalAlign' => 'bottom',
  513. 'floating' => true,
  514. 'x' => -5,
  515. 'y' => -30,
  516. 'style' => array('color' => '#555555', 'fontSize' => '0.8em'),
  517. ),
  518. 'legend' => array(
  519. 'verticalAlign' => 'top',
  520. 'y' => 20,
  521. ),
  522. 'series' => array(
  523. array(
  524. 'name' => $component['component_title'],
  525. 'data' => $component['named_points'],
  526. 'pointStart' => $parameters['point_start_js_timestamp'],
  527. 'pointInterval' => $parameters['point_interval'],
  528. ),
  529. ),
  530. 'credits' => array(
  531. 'text' => 'Graph courtesy of Economic Research Southern Africa',
  532. 'href' => 'http://www.econrsa.org',
  533. ),
  534. );
  535. // Set up our html framework for the graph
  536. $html .= '<div id="chart-component-' . $key . '" style="width:650px; height:500px;"></div>';
  537. //$charts['highcharts_settings'][$key] = $options['highcharts_settings'];
  538. $chart['html'] = $html;
  539. $chart['settings'] = $highcharts_settings;
  540.  
  541. return $chart;
  542. }
  543. /**
  544. * Add the javascript and html for displaying the linear mpv graph
  545. *
  546. */
  547. function econrsa_graphs_setup_mpv_linear($id, $parameters) {
  548. // Prepare the highcharts settings for this type of graph
  549. // Graph configuration
  550. $highcharts_settings = array(
  551. 'chart' => array(
  552. 'renderTo' => 'chart-' . $parameters['id'],
  553. 'zoomType' => 'x',
  554. ),
  555. 'xAxis' => array(
  556. 'type' => 'datetime',
  557. ),
  558. 'yAxis' => array(
  559. 'title' => array('text' => 'Value'),
  560. ),
  561. 'title' => array(
  562. 'text' => $parameters['title'],
  563. 'style' => array('color' => '#000000', 'fontSize' => '14px', 'fontWeight' => 'bold'),
  564. ),
  565. 'subtitle' => array(
  566. 'text' => t('Data last updated: @modified_date at @modified_time.',
  567. array('@modified_date' => $parameters['meta']['modified_date'], '@modified_time' => $parameters['meta']['modified_time'])),
  568. 'align' => 'right',
  569. 'verticalAlign' => 'bottom',
  570. 'floating' => true,
  571. 'x' => -5,
  572. 'y' => -30,
  573. 'style' => array('color' => '#555555', 'fontSize' => '0.8em'),
  574. ),
  575. 'legend' => array(
  576. 'verticalAlign' => 'top',
  577. 'y' => 20,
  578. ),
  579. 'series' => array(
  580. array(
  581. 'name' => $parameters['series_title'],
  582. 'data' => $parameters['named_points'],
  583. 'pointStart' => $parameters['point_start_js_timestamp'],
  584. 'pointInterval' => $parameters['point_interval'],
  585. ),
  586. ),
  587. 'credits' => array(
  588. 'text' => 'Graph courtesy of Economic Research Southern Africa',
  589. 'href' => 'http://www.econrsa.org',
  590. ),
  591. 'exporting' => array(
  592. 'filename' => strtolower(str_replace(' ', '-', $parameters['title'])),
  593. 'sourceWidth' => 1000,
  594. 'sourceHeight' => 750,
  595. ),
  596. );
  597. // Set up our html framework for the graph
  598. $html = '<div id="chart-' . $parameters['id'] . '" style="width:100%; height:500px;"></div>';
  599. $html .= '<button id="btn-threshold" class="autocompare">Show thresholds</button>';
  600. $html .= '<div id="threshold-container" class="ersa-graphs-threshold-container">';
  601. $html .= 'Threshold value: <input type="text" name="threshold" id="threshold" size="3" value=' . ECONRSA_GRAPHS_THRESHOLD_DEFAULT . '>';
  602. $html .= '<button id="btn-threshold-update">Update thresholds</button>';
  603. $html .= '</div>';
  604. $html .= '<div id="graph-description" class="ersa-graphs-description">';
  605. $html .= $parameters['description'];
  606. $html .= '</div>';
  607.  
  608. $chart['html'] = $html;
  609. $chart['settings'] = $highcharts_settings;
  610. return $chart;
  611. }
  612.  
  613. /**
  614. * Add the javascript and html for displaying the mpv spider graph
  615. */
  616. function econrsa_graphs_setup_mpv_components($parameters) {
  617. //// The combined mvp series
  618. //$multiple_series[] = array(
  619. // 'name' => $parameters['series_title'],
  620. // 'data' => $parameters['named_points'],
  621. // 'pointStart' => $parameters['point_start_js_timestamp'],
  622. // 'pointInterval' => $parameters['point_interval'],
  623. //);
  624. // Set up the components
  625. foreach($parameters['multiple_components'] as $component) {
  626. $multiple_series[] = array(
  627. 'name' => $component['component_title'],
  628. 'data' => $component['named_points'],
  629. 'pointStart' => $parameters['point_start_js_timestamp'],
  630. 'pointInterval' => $parameters['point_interval'],
  631. 'pointPlacement' => 'on',
  632. );
  633. }
  634. $highcharts_settings = array(
  635. 'chart' => array(
  636. 'renderTo' => 'chart-components-' . $parameters['id'],
  637. 'zoomType' => 'x',
  638. ),
  639. 'xAxis' => array(
  640. 'type' => 'datetime',
  641. ),
  642. 'yAxis' => array(
  643. 'title' => array('text' => 'Value'),
  644. ),
  645. 'title' => array(
  646. 'text' => $parameters['title'],
  647. 'style' => array('color' => '#000000', 'fontSize' => '14px', 'fontWeight' => 'bold'),
  648. ),
  649. 'subtitle' => array(
  650. 'text' => t('Data last updated: @modified_date at @modified_time.',
  651. array('@modified_date' => $parameters['meta']['modified_date'], '@modified_time' => $parameters['meta']['modified_time'])),
  652. 'align' => 'right',
  653. 'verticalAlign' => 'bottom',
  654. 'floating' => true,
  655. 'x' => -5,
  656. 'y' => -30,
  657. 'style' => array('color' => '#555555', 'fontSize' => '0.8em'),
  658. ),
  659. 'series' => $multiple_series,
  660. 'credits' => array(
  661. 'text' => 'Graph courtesy of Economic Research Southern Africa',
  662. 'href' => 'http://www.econrsa.org',
  663. ),
  664. 'legend' => array(
  665. 'verticalAlign' => 'top',
  666. 'y' => 20,
  667. 'title' => array(
  668. 'text' => t('Click on any of the component names in the legend below to remove them from the display.'),
  669. 'style' => array(
  670. 'fontWeight' => 'normal',
  671. 'color' => 'gray',
  672. ),
  673. ),
  674. ),
  675. 'exporting' => array(
  676. 'filename' => strtolower(str_replace(' ', '-', $parameters['title'])),
  677. 'sourceWidth' => 1000,
  678. 'sourceHeight' => 750,
  679. ),
  680. );
  681. // Set up our html framework for the graph
  682. $html = '<div id="chart-components-' . $parameters['id'] . '" style="width:100%; height:500px;"></div>';
  683.  
  684. $chart['html'] = $html;
  685. $chart['settings'] = $highcharts_settings;
  686. return $chart;
  687.  
  688. }
  689.  
  690.  
  691. /**
  692. * Add the javascript and html for displaying the mpv spider graph
  693. */
  694. function econrsa_graphs_setup_mpv_spider($parameters) {
  695.  
  696. $render_id = 'chart-spider-' . $parameters['id'];
  697. $start_time = $parameters['point_start_js_timestamp'];
  698. // Spider graph is not part of the default highcharts js library
  699. drupal_add_js(libraries_get_path('highcharts') . '/js/highcharts-more.js');
  700. foreach($parameters['multiple_components'] as $component) {
  701. $multiple_series[] = array(
  702. 'name' => $component['component_title'],
  703. 'data' => $component['named_points'],
  704. 'pointStart' => $start_time,
  705. 'pointInterval' => $parameters['point_interval'],
  706. 'pointPlacement' => 'on',
  707. );
  708. }
  709. // Prepare the highcharts settings for this type of graph
  710. // Graph configuration
  711. $highcharts_settings = array(
  712. 'chart' => array(
  713. 'renderTo' => $render_id,
  714. 'polar' => true,
  715. 'type' => 'line',
  716. 'zoomType' => 'y',
  717. ),
  718. 'xAxis' => array(
  719. 'type' => 'datetime',
  720. 'tickmarkPlacement' => 'on',
  721. 'lineWidth' => 0,
  722. //'categories' => array('Sales', 'Marketing', 'Development', 'Customer Support', 'Information Technology', 'Administration'),
  723. ),
  724. 'yAxis' => array(
  725. 'title' => array('text' => 'Value'),
  726. 'gridLineInterpolation' => 'polygon',
  727. 'lineWidth' => 0,
  728.  
  729. ),
  730. 'pane' => array(
  731. 'size' => '80%',
  732. ),
  733. 'title' => array(
  734. 'text' => $parameters['title'],
  735. 'style' => array('color' => '#000000', 'fontSize' => '14px', 'fontWeight' => 'bold'),
  736. ),
  737. 'subtitle' => array(
  738. 'text' => t('Data last updated: @modified_date at @modified_time.',
  739. array('@modified_date' => $parameters['meta']['modified_date'], '@modified_time' => $parameters['meta']['modified_time'])),
  740. 'align' => 'right',
  741. 'verticalAlign' => 'bottom',
  742. 'floating' => true,
  743. 'x' => -5,
  744. 'y' => -30,
  745. 'style' => array('color' => '#555555', 'fontSize' => '0.8em'),
  746. ),
  747. 'legend' => array(
  748. 'verticalAlign' => 'top',
  749. 'y' => 20,
  750. 'title' => array(
  751. 'text' => t('Click on any of the component names in the legend below to remove them from the display.'),
  752. 'style' => array(
  753. 'fontWeight' => 'normal',
  754. 'color' => 'gray',
  755. ),
  756. ),
  757. ),
  758. 'series' => $multiple_series,
  759. 'credits' => array(
  760. 'text' => 'Graph courtesy of Economic Research Southern Africa',
  761. 'href' => 'http://www.econrsa.org',
  762. ),
  763. );
  764. $html .= '<div id="' . $render_id . '" style="width:650px; height:780px;"></div>';
  765. $chart['html'] = $html;
  766. $chart['settings'] = $highcharts_settings;
  767. return $chart;
  768. }
  769.  
  770. /**
  771. * Test function: to test excel reading
  772. *
  773. */
  774.  
  775. function _text_extraction() {
  776. $library = libraries_load('PHPExcel');
  777. // check file exists
  778. $graph_file = ECONRSA_GRAPHS_FILE_PATH . '/_test_cpi.xlsx';
  779.  
  780. if (is_readable($graph_file)) {
  781. // Initialise the excel reader and fetch the sheet data
  782. try {
  783. $input_file_type = PHPExcel_IOFactory::identify($graph_file);
  784. $obj_reader = PHPExcel_IOFactory::createReader($input_file_type);
  785. $obj_reader->setReadDataOnly(TRUE);
  786. $obj_php_excel = $obj_reader->load($graph_file);
  787. } catch (Exception $e) {
  788. die('Error loading file "' . pathinfo($graph_file, PATHINFO_BASENAME)
  789. . '": ' . $e->getMessage());
  790. }
  791. // Get worksheet dimensions
  792. $sheet = $obj_php_excel->getSheet(0);
  793. $extracted_values = $sheet->rangeToArray('AD4:AD5', NULL, TRUE, FALSE);
  794. //dpm($extracted_values);
  795. }
  796.  
  797. }
  798.  
  799. function econrsa_graphs_setup_tabs ($mpv, $spider, $components) {
  800.  
  801. // Setup combined mpv tab
  802. $tabs[] = array(
  803. 'hide_title' => 0,
  804. 'title' => t('Linear MPV components'), // Tab title.
  805. 'contents' => $components['html'],
  806. );
  807. // Setup spider tab
  808. $tabs[] = array(
  809. 'hide_title' => 0,
  810. //'title' => $spider['settings']['title']['text'], // Tab title.
  811. 'title' => t('Components Spider'), // Tab title.
  812. 'contents' => $spider['html'],
  813. );
  814. //foreach ($components as $key => $component) {
  815. // $tabs[] = array(
  816. // 'hide_title' => 0,
  817. // //'title' => $component['settings']['title']['text'], // Tab title.
  818. // 'title' => 'X' . ($key + 1), // Tab title.
  819. // 'contents' => $component['html'],
  820. // );
  821. //}
  822.  
  823. $name = 'qt_ersa_graphs_components';
  824. $overrides = array(
  825. 'ajax' => FALSE, // TRUE or FALSE.
  826. 'hide_empty_tabs' => FALSE, // TRUE or FALSE.
  827. 'renderer' => 'quicktabs', // 'accordion', 'quicktabs'
  828. 'style' => 'Zen',
  829. 'default_tab' => 0,
  830. );
  831. $html = drupal_render(quicktabs_build_quicktabs($name, $overrides, $tabs));
  832. return $html;
  833. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement