vis.js is a dynamic, browser-based visualization library

209 lines
5.0 KiB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. var Hammer = require('../../../module/hammer');
  2. /**
  3. * @constructor Item
  4. * @param {Object} data Object containing (optional) parameters type,
  5. * start, end, content, group, className.
  6. * @param {{toScreen: function, toTime: function}} conversion
  7. * Conversion functions from time to screen and vice versa
  8. * @param {Object} options Configuration options
  9. * // TODO: describe available options
  10. */
  11. function Item (data, conversion, options) {
  12. this.id = null;
  13. this.parent = null;
  14. this.data = data;
  15. this.dom = null;
  16. this.conversion = conversion || {};
  17. this.options = options || {};
  18. this.selected = false;
  19. this.displayed = false;
  20. this.dirty = true;
  21. this.top = null;
  22. this.left = null;
  23. this.width = null;
  24. this.height = null;
  25. }
  26. /**
  27. * Select current item
  28. */
  29. Item.prototype.select = function() {
  30. this.selected = true;
  31. this.dirty = true;
  32. if (this.displayed) this.redraw();
  33. };
  34. /**
  35. * Unselect current item
  36. */
  37. Item.prototype.unselect = function() {
  38. this.selected = false;
  39. this.dirty = true;
  40. if (this.displayed) this.redraw();
  41. };
  42. /**
  43. * Set data for the item. Existing data will be updated. The id should not
  44. * be changed. When the item is displayed, it will be redrawn immediately.
  45. * @param {Object} data
  46. */
  47. Item.prototype.setData = function(data) {
  48. this.data = data;
  49. this.dirty = true;
  50. if (this.displayed) this.redraw();
  51. };
  52. /**
  53. * Set a parent for the item
  54. * @param {ItemSet | Group} parent
  55. */
  56. Item.prototype.setParent = function(parent) {
  57. if (this.displayed) {
  58. this.hide();
  59. this.parent = parent;
  60. if (this.parent) {
  61. this.show();
  62. }
  63. }
  64. else {
  65. this.parent = parent;
  66. }
  67. };
  68. /**
  69. * Check whether this item is visible inside given range
  70. * @returns {{start: Number, end: Number}} range with a timestamp for start and end
  71. * @returns {boolean} True if visible
  72. */
  73. Item.prototype.isVisible = function(range) {
  74. // Should be implemented by Item implementations
  75. return false;
  76. };
  77. /**
  78. * Show the Item in the DOM (when not already visible)
  79. * @return {Boolean} changed
  80. */
  81. Item.prototype.show = function() {
  82. return false;
  83. };
  84. /**
  85. * Hide the Item from the DOM (when visible)
  86. * @return {Boolean} changed
  87. */
  88. Item.prototype.hide = function() {
  89. return false;
  90. };
  91. /**
  92. * Repaint the item
  93. */
  94. Item.prototype.redraw = function() {
  95. // should be implemented by the item
  96. };
  97. /**
  98. * Reposition the Item horizontally
  99. */
  100. Item.prototype.repositionX = function() {
  101. // should be implemented by the item
  102. };
  103. /**
  104. * Reposition the Item vertically
  105. */
  106. Item.prototype.repositionY = function() {
  107. // should be implemented by the item
  108. };
  109. /**
  110. * Repaint a delete button on the top right of the item when the item is selected
  111. * @param {HTMLElement} anchor
  112. * @protected
  113. */
  114. Item.prototype._repaintDeleteButton = function (anchor) {
  115. if (this.selected && this.options.editable.remove && !this.dom.deleteButton) {
  116. // create and show button
  117. var me = this;
  118. var deleteButton = document.createElement('div');
  119. deleteButton.className = 'delete';
  120. deleteButton.title = 'Delete this item';
  121. Hammer(deleteButton, {
  122. preventDefault: true
  123. }).on('tap', function (event) {
  124. me.parent.removeFromDataSet(me);
  125. event.stopPropagation();
  126. });
  127. anchor.appendChild(deleteButton);
  128. this.dom.deleteButton = deleteButton;
  129. }
  130. else if (!this.selected && this.dom.deleteButton) {
  131. // remove button
  132. if (this.dom.deleteButton.parentNode) {
  133. this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton);
  134. }
  135. this.dom.deleteButton = null;
  136. }
  137. };
  138. /**
  139. * Set HTML contents for the item
  140. * @param {Element} element HTML element to fill with the contents
  141. * @private
  142. */
  143. Item.prototype._updateContents = function (element) {
  144. if (this.data.content instanceof Element) {
  145. element.innerHTML = '';
  146. element.appendChild(this.data.content);
  147. }
  148. else if (this.data.content != undefined) {
  149. element.innerHTML = this.data.content;
  150. }
  151. else {
  152. throw new Error('Property "content" missing in item ' + this.data.id);
  153. }
  154. };
  155. /**
  156. * Set HTML contents for the item
  157. * @param {Element} element HTML element to fill with the contents
  158. * @private
  159. */
  160. Item.prototype._updateTitle = function (element) {
  161. if (this.data.title != null) {
  162. element.title = this.data.title || '';
  163. }
  164. else {
  165. element.removeAttribute('title');
  166. }
  167. };
  168. /**
  169. * Process dataAttributes timeline option and set as data- attributes on dom.content
  170. * @param {Element} element HTML element to which the attributes will be attached
  171. * @private
  172. */
  173. Item.prototype._updateDataAttributes = function(element) {
  174. if (this.options.dataAttributes && this.options.dataAttributes.length > 0) {
  175. for (var i = 0; i < this.options.dataAttributes.length; i++) {
  176. var name = this.options.dataAttributes[i];
  177. var value = this.data[name];
  178. if (value != null) {
  179. element.setAttribute('data-' + name, value);
  180. }
  181. else {
  182. element.removeAttribute('data-' + name);
  183. }
  184. }
  185. }
  186. };
  187. module.exports = Item;