1. /**
  2. * @module meteoJS/timeline/visualisation/bsButtons
  3. */
  4. import $ from 'jquery';
  5. import Visualisation from '../Visualisation.js';
  6. /**
  7. * Dynamic format string to output the time for each Time-Button.
  8. *
  9. * @typedef {Function} module:meteoJS/timeline/visualisation/bsButtons~timeFormatFunction
  10. * @param {Date} time - Timestamp of the Button.
  11. * @returns {String} A string to format the time for the Time-Buttons.
  12. */
  13. /**
  14. * Options for constructor.
  15. *
  16. * @typedef {module:meteoJS/timeline/visualisation~options}
  17. * module:meteoJS/timeline/visualisation/bsButtons~options
  18. * @property {String|module:meteoJS/timeline/visualisation/bsButtons~timeFormatFunction} [format='HH']
  19. * Format-String for the time of the Time-Buttons.
  20. */
  21. /**
  22. * Show timeline as a group of buttons.
  23. *
  24. * <pre><code>import bsButtons from 'meteojs/timeline/visualisation/bsButtons';</code></pre>
  25. *
  26. * @extends module:meteoJS/timeline/visualisation.Visualisation
  27. */
  28. export class bsButtons extends Visualisation {
  29. /**
  30. * @param {module:meteoJS/timeline/visualisation/bsButtons~options} options - Options.
  31. */
  32. constructor({
  33. format = 'HH',
  34. grouping = 'daily',
  35. groupingFormat = 'ddd, DD. MMM',
  36. classMain = 'btn-toolbar',
  37. classButtonGroup = 'btn-group',
  38. classButtonGroupMargin = 'me-2',
  39. classLabel = undefined,
  40. classLabelSpan = 'd-block w-100',
  41. classButton = 'btn',
  42. classButtonActive = 'active',
  43. classButtonNotEnabled = 'btn-light',
  44. classButtonEnabled = 'btn-secondary',
  45. classButtonAllEnabled = 'btn-primary',
  46. /*prependNodes = undefined,
  47. appendNodes = undefined*/
  48. ...rest
  49. } = {}) {
  50. super(rest);
  51. this.options.format = format;
  52. this.options.grouping = grouping;
  53. this.options.groupingFormat = groupingFormat;
  54. this.options.classMain = classMain;
  55. this.options.classButtonGroup = classButtonGroup;
  56. this.options.classButtonGroupMargin = classButtonGroupMargin;
  57. this.options.classLabel = classLabel;
  58. this.options.classLabelSpan = classLabelSpan;
  59. this.options.classButton = classButton;
  60. this.options.classButtonActive = classButtonActive;
  61. this.options.classButtonNotEnabled = classButtonNotEnabled;
  62. this.options.classButtonEnabled = classButtonEnabled;
  63. this.options.classButtonAllEnabled = classButtonAllEnabled;
  64. /**
  65. * @member {external:jQuery|undefined}
  66. * @private
  67. */
  68. this.toolbarNode = undefined;
  69. this.setNode(this.options.node);
  70. }
  71. /**
  72. * @inheritdoc
  73. */
  74. onChangeTime() {
  75. if (this.toolbarNode === undefined)
  76. return;
  77. var time = this.options.timeline.getSelectedTime();
  78. var that = this;
  79. this.toolbarNode.find('button').each(function () {
  80. var t = new Date(+$(this).data('time'));
  81. $(this)
  82. .removeClass(that.options.classButtonActive);
  83. /*.removeClass(that.options.classButtonAllEnabled)
  84. .removeClass(that.options.classButtonEnabled)
  85. .removeClass(that.options.classButtonNotEnabled);*/
  86. if (time.valueOf() == t.valueOf())
  87. $(this).addClass(that.options.classButtonActive);
  88. /*else if (that.options.timeline.isTimeAllEnabled(t))
  89. $(this).addClass(that.options.classButtonAllEnabled);
  90. else if (that.options.timeline.isTimeEnabled(t))
  91. $(this).addClass(that.options.classButtonEnabled);
  92. else
  93. $(this).addClass(that.options.classButtonNotEnabled);*/
  94. });
  95. }
  96. /**
  97. * @inheritdoc
  98. */
  99. onChangeTimes() {
  100. if (this.toolbarNode === undefined)
  101. this.toolbarNode = $('<div>');
  102. this.toolbarNode.empty();
  103. var groupingFormat =
  104. (this.options.grouping == 'daily') ? 'YYYY-MM-DD' :
  105. (this.options.grouping == 'hourly') ? 'YYYY-MM-DD HH' :
  106. this.options.grouping;
  107. var lastNode = undefined;
  108. this.getTimelineTimes().forEach(function (time) {
  109. if (lastNode === undefined ||
  110. lastNode.data('date') != this.timeToText(time, groupingFormat)) {
  111. var btnGroup = $('<div>')
  112. .addClass(this.options.classButtonGroup)
  113. .addClass(this.options.classButtonGroupMargin)
  114. .attr('role', 'group')
  115. .attr('aria-label', this.timeToText(time, groupingFormat));
  116. if (this.options.groupingFormat === undefined) {
  117. lastNode = btnGroup;
  118. }
  119. else {
  120. var span = $('<span>')
  121. .addClass(this.options.classLabelSpan)
  122. .text(this.timeToText(time, this.options.groupingFormat));
  123. lastNode = $('<label>')
  124. .addClass(this.options.classLabel)
  125. .append(span);
  126. btnGroup.attr('aria-label', span.text());
  127. lastNode.append(btnGroup);
  128. }
  129. lastNode.data('date', this.timeToText(time, groupingFormat));
  130. this.toolbarNode.append(lastNode);
  131. }
  132. var btn = $('<button>')
  133. .addClass(this.options.classButton)
  134. .attr('type', 'button')
  135. .data('time', time.valueOf());
  136. if (typeof this.options.format == 'function')
  137. btn.text(this.timeToText(time, this.options.format.call(this, time)));
  138. else
  139. btn.text(this.timeToText(time, this.options.format));
  140. if (this.options.timeline.isTimeAllEnabled(time))
  141. btn.addClass(this.options.classButtonAllEnabled);
  142. else if (this.options.timeline.isTimeEnabled(time))
  143. btn.addClass(this.options.classButtonEnabled);
  144. else
  145. btn.addClass(this.options.classButtonNotEnabled);
  146. let selectedTime = this.options.timeline.getSelectedTime();
  147. if (time.valueOf() == selectedTime.valueOf())
  148. btn.addClass(this.options.classButtonActive);
  149. var that = this;
  150. btn.click(function () {
  151. that.options.timeline.setSelectedTime(new Date(+$(this).data('time')));
  152. that.trigger('input');
  153. });
  154. if (lastNode.hasClass(this.options.classButtonGroup))
  155. lastNode.append(btn);
  156. else
  157. lastNode.children('div').append(btn);
  158. }, this);
  159. this.toolbarNode.find('div.'+this.options.classButtonGroup).last().removeClass(this.options.classButtonGroupMargin);
  160. }
  161. /**
  162. * @inheritdoc
  163. */
  164. emptyNode() {
  165. this.toolbarNode = undefined;
  166. this.options.node.empty();
  167. }
  168. /**
  169. * @inheritdoc
  170. */
  171. onInitNode() {
  172. this.toolbarNode = $('<div>')
  173. .addClass(this.options.classMain)
  174. .attr('role', 'toolbar')
  175. .attr('aria-label', 'Timeline toolbar');
  176. this.options.node.append(this.toolbarNode);
  177. }
  178. }
  179. export default bsButtons;