vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
5.8 KiB

12 years ago
12 years ago
  1. /**
  2. * @constructor ItemPoint
  3. * @extends Item
  4. * @param {ItemSet} parent
  5. * @param {Object} data Object containing parameters start
  6. * content, className.
  7. * @param {Object} [options] Options to set initial property values
  8. * // TODO: describe available options
  9. */
  10. function ItemPoint (parent, data, options) {
  11. this.props = {
  12. dot: {
  13. top: 0,
  14. width: 0,
  15. height: 0
  16. },
  17. content: {
  18. height: 0,
  19. marginLeft: 0
  20. }
  21. };
  22. Item.call(this, parent, data, options);
  23. }
  24. ItemPoint.prototype = new Item (null, null);
  25. // register the ItemPoint in the item types
  26. itemTypes['point'] = ItemPoint;
  27. /**
  28. * Select the item
  29. * @override
  30. */
  31. ItemPoint.prototype.select = function () {
  32. this.selected = true;
  33. // TODO: select and unselect
  34. };
  35. /**
  36. * Unselect the item
  37. * @override
  38. */
  39. ItemPoint.prototype.unselect = function () {
  40. this.selected = false;
  41. // TODO: select and unselect
  42. };
  43. /**
  44. * Repaint the item
  45. * @return {Boolean} changed
  46. */
  47. ItemPoint.prototype.repaint = function () {
  48. // TODO: make an efficient repaint
  49. var changed = false;
  50. var dom = this.dom;
  51. if (this.visible) {
  52. if (!dom) {
  53. this._create();
  54. changed = true;
  55. }
  56. dom = this.dom;
  57. if (dom) {
  58. if (!this.options && !this.options.parent) {
  59. throw new Error('Cannot repaint item: no parent attached');
  60. }
  61. var parentContainer = this.parent.getContainer();
  62. if (!parentContainer) {
  63. throw new Error('Cannot repaint time axis: parent has no container element');
  64. }
  65. if (!dom.point.parentNode) {
  66. parentContainer.appendChild(dom.point);
  67. changed = true;
  68. }
  69. // update contents
  70. if (this.data.content != this.content) {
  71. this.content = this.data.content;
  72. if (this.content instanceof Element) {
  73. dom.content.innerHTML = '';
  74. dom.content.appendChild(this.content);
  75. }
  76. else if (this.data.content != undefined) {
  77. dom.content.innerHTML = this.content;
  78. }
  79. else {
  80. throw new Error('Property "content" missing in item ' + this.data.id);
  81. }
  82. changed = true;
  83. }
  84. // update class
  85. var className = (this.data.className? ' ' + this.data.className : '') +
  86. (this.selected ? ' selected' : '');
  87. if (this.className != className) {
  88. this.className = className;
  89. dom.point.className = 'item point' + className;
  90. changed = true;
  91. }
  92. }
  93. }
  94. else {
  95. // hide when visible
  96. if (dom) {
  97. if (dom.point.parentNode) {
  98. dom.point.parentNode.removeChild(dom.point);
  99. changed = true;
  100. }
  101. }
  102. }
  103. return changed;
  104. };
  105. /**
  106. * Reflow the item: calculate its actual size from the DOM
  107. * @return {boolean} resized returns true if the axis is resized
  108. * @override
  109. */
  110. ItemPoint.prototype.reflow = function () {
  111. if (this.data.start == undefined) {
  112. throw new Error('Property "start" missing in item ' + this.data.id);
  113. }
  114. var update = util.updateProperty,
  115. dom = this.dom,
  116. props = this.props,
  117. options = this.options,
  118. orientation = options.orientation,
  119. start = this.parent.toScreen(this.data.start),
  120. changed = 0,
  121. top;
  122. if (dom) {
  123. changed += update(this, 'width', dom.point.offsetWidth);
  124. changed += update(this, 'height', dom.point.offsetHeight);
  125. changed += update(props.dot, 'width', dom.dot.offsetWidth);
  126. changed += update(props.dot, 'height', dom.dot.offsetHeight);
  127. changed += update(props.content, 'height', dom.content.offsetHeight);
  128. if (orientation == 'top') {
  129. top = options.margin.axis;
  130. }
  131. else {
  132. // default or 'bottom'
  133. var parentHeight = this.parent.height;
  134. top = Math.max(parentHeight - this.height - options.margin.axis, 0);
  135. }
  136. changed += update(this, 'top', top);
  137. changed += update(this, 'left', start - props.dot.width / 2);
  138. changed += update(props.content, 'marginLeft', 1.5 * props.dot.width);
  139. //changed += update(props.content, 'marginRight', 0.5 * props.dot.width); // TODO
  140. changed += update(props.dot, 'top', (this.height - props.dot.height) / 2);
  141. }
  142. else {
  143. changed += 1;
  144. }
  145. return (changed > 0);
  146. };
  147. /**
  148. * Create an items DOM
  149. * @private
  150. */
  151. ItemPoint.prototype._create = function () {
  152. var dom = this.dom;
  153. if (!dom) {
  154. this.dom = dom = {};
  155. // background box
  156. dom.point = document.createElement('div');
  157. // className is updated in repaint()
  158. // contents box, right from the dot
  159. dom.content = document.createElement('div');
  160. dom.content.className = 'content';
  161. dom.point.appendChild(dom.content);
  162. // dot at start
  163. dom.dot = document.createElement('div');
  164. dom.dot.className = 'dot';
  165. dom.point.appendChild(dom.dot);
  166. }
  167. };
  168. /**
  169. * Reposition the item, recalculate its left, top, and width, using the current
  170. * range and size of the items itemset
  171. * @override
  172. */
  173. ItemPoint.prototype.reposition = function () {
  174. var dom = this.dom,
  175. props = this.props;
  176. if (dom) {
  177. dom.point.style.top = this.top + 'px';
  178. dom.point.style.left = this.left + 'px';
  179. dom.content.style.marginLeft = props.content.marginLeft + 'px';
  180. //dom.content.style.marginRight = props.content.marginRight + 'px'; // TODO
  181. dom.dot.style.top = props.dot.top + 'px';
  182. }
  183. };