TimelineHelper.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. namespace Tools\View\Helper;
  3. use Cake\View\Helper;
  4. use Cake\View\View;
  5. /**
  6. * TimelineHelper for easy output of a timeline with multiple items.
  7. *
  8. * You need to include your css and js file, manually:
  9. *
  10. * echo $this->Html->script('timeline/timeline');
  11. * echo $this->Html->css('/js/timeline/timeline');
  12. *
  13. * @link http://almende.github.io/chap-links-library/timeline.html
  14. * @author Mark Scherer
  15. * @license MIT
  16. */
  17. class TimelineHelper extends Helper {
  18. public $helpers = array('Tools.Js');
  19. protected $_defaultConfig = array(
  20. 'id' => 'mytimeline',
  21. 'selectable' => false,
  22. 'editable' => false,
  23. 'min' => null, // Min date.
  24. 'max' => null, // Max date.
  25. 'width' => '100%',
  26. 'height' => null, // Auto.
  27. 'style' => 'box',
  28. 'current' => null, // Current time.
  29. );
  30. protected $_items = array();
  31. /**
  32. * Apply settings and merge them with the defaults.
  33. *
  34. * Possible values are (with their default values):
  35. * - 'min',
  36. * - 'max',
  37. * - 'width'
  38. * - 'height'
  39. * - 'minHeight'
  40. * - 'selectable' => false,
  41. * - 'editable' => false,
  42. * - 'moveable' => true
  43. * - 'animate' => true,
  44. * - 'animateZoom' => true,
  45. * - 'axisOnTop' => false,
  46. * - 'cluster' => false
  47. * - 'locale' (string)
  48. * - 'style' (string)
  49. * - ...
  50. *
  51. * @link http://almende.github.io/chap-links-library/js/timeline/doc/
  52. * @param array $settings Key value pairs to merge with current settings.
  53. * @return void
  54. * @deprecated
  55. */
  56. public function settings($settings) {
  57. $this->config($settings);
  58. }
  59. /**
  60. * Add timeline item.
  61. *
  62. * Requires at least:
  63. * - start (date or datetime)
  64. * - content (string)
  65. * Further data options:
  66. * - end (date or datetime)
  67. * - group (string)
  68. * - className (string)
  69. * - editable (boolean)
  70. *
  71. * @link http://almende.github.io/chap-links-library/js/timeline/doc/
  72. * @param array
  73. * @return void
  74. */
  75. public function addItem($item) {
  76. $this->_items[] = $item;
  77. }
  78. /**
  79. * Add timeline items as an array of items.
  80. *
  81. * @see TimelineHelper::addItem()
  82. * @return void
  83. */
  84. public function addItems($items) {
  85. foreach ($items as $item) {
  86. $this->_items[] = $item;
  87. }
  88. }
  89. /**
  90. * Finalize the timeline and write the javascript to the buffer.
  91. * Make sure that your view does also output the buffer at some place!
  92. *
  93. * @param bool $return If the output should be returned instead
  94. * @return void|string Javascript if $return is true
  95. */
  96. public function finalize($return = false) {
  97. $settings = $this->config();
  98. $timelineId = $settings['id'];
  99. $data = $this->_format($this->_items);
  100. $current = '';
  101. if ($settings['current']) {
  102. $dateString = date('Y-m-d H:i:s', time());
  103. $current = 'timeline.setCurrentTime(' . $this->_date($dateString) . ');';
  104. }
  105. unset($settings['id']);
  106. unset($settings['current']);
  107. $options = $this->_options($settings);
  108. $script = <<<JS
  109. var timeline;
  110. var data;
  111. var options;
  112. // Called when the Visualization API is loaded.
  113. function drawVisualization() {
  114. // Create a JSON data table
  115. data = $data
  116. options = $options
  117. // Instantiate our timeline object.
  118. timeline = new links.Timeline(document.getElementById('$timelineId'));
  119. // Draw our timeline with the created data and options
  120. timeline.draw(data, options);
  121. $current
  122. }
  123. drawVisualization();
  124. JS;
  125. if ($return) {
  126. return $script;
  127. }
  128. $this->Js->buffer($script);
  129. }
  130. /**
  131. * Format options to JS code
  132. *
  133. * @param array $options
  134. * @return string
  135. */
  136. protected function _options($options) {
  137. $e = array();
  138. foreach ($options as $option => $value) {
  139. if ($value === null) {
  140. continue;
  141. }
  142. if (is_string($value)) {
  143. $value = '\'' . $value . '\'';
  144. } elseif (is_object($value)) { // Datetime?
  145. $value = $this->_date($value);
  146. } elseif (is_bool($value)) {
  147. $value = $value ? 'true' : 'false';
  148. } else {
  149. $value = str_replace('\'', '\\\'', $value);
  150. }
  151. $e[] = '\'' . $option . '\': ' . $value;
  152. }
  153. $string = '{' . PHP_EOL . "\t" . implode(',' . PHP_EOL . "\t", $e) . PHP_EOL . '}';
  154. return $string;
  155. }
  156. /**
  157. * Format items to JS code
  158. *
  159. * @see TimelineHelper::addItem()
  160. * @param array $items
  161. * @return string
  162. */
  163. protected function _format($items) {
  164. $e = array();
  165. foreach ($items as $item) {
  166. $tmp = array();
  167. foreach ($item as $key => $row) {
  168. switch ($key) {
  169. case 'editable':
  170. $tmp[] = $row ? 'true' : 'false';
  171. break;
  172. case 'start':
  173. case 'end':
  174. $tmp[] = '\'' . $key . '\': ' . $this->_date($row);
  175. break;
  176. default:
  177. $tmp[] = '\'' . $key . '\': \'' . str_replace('\'', '\\\'', $row) . '\'';
  178. }
  179. }
  180. $e[] = '{' . implode(',' . PHP_EOL, $tmp) . '}';
  181. }
  182. $string = '[' . implode(',' . PHP_EOL, $e) . '];';
  183. return $string;
  184. }
  185. /**
  186. * Format date to JS code.
  187. *
  188. * @param \DateTime $date
  189. * @return string
  190. */
  191. protected function _date($date = null) {
  192. if ($date === null || !$date instanceof \DateTime) {
  193. return '';
  194. }
  195. $datePieces = array();
  196. $datePieces[] = $date->format('Y');
  197. // JavaScript uses 0-indexed months, so we need to subtract 1 month from PHP's output
  198. $datePieces[] = (int)($date->format('m') - 1);
  199. $datePieces[] = (int)$date->format('d');
  200. $datePieces[] = (int)$date->format('H');
  201. $datePieces[] = (int)$date->format('i');
  202. $datePieces[] = (int)$date->format('s');
  203. return 'new Date(' . implode(', ', $datePieces) . ')';
  204. }
  205. }