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.

219 lines
7.3 KiB

10 years ago
  1. // DOM utility methods
  2. /**
  3. * this prepares the JSON container for allocating SVG elements
  4. * @param {Object} JSONcontainer
  5. * @private
  6. */
  7. exports.prepareElements = function(JSONcontainer) {
  8. // cleanup the redundant svgElements;
  9. for (var elementType in JSONcontainer) {
  10. if (JSONcontainer.hasOwnProperty(elementType)) {
  11. JSONcontainer[elementType].redundant = JSONcontainer[elementType].used;
  12. JSONcontainer[elementType].used = [];
  13. }
  14. }
  15. };
  16. /**
  17. * this cleans up all the unused SVG elements. By asking for the parentNode, we only need to supply the JSON container from
  18. * which to remove the redundant elements.
  19. *
  20. * @param {Object} JSONcontainer
  21. * @private
  22. */
  23. exports.cleanupElements = function(JSONcontainer) {
  24. // cleanup the redundant svgElements;
  25. for (var elementType in JSONcontainer) {
  26. if (JSONcontainer.hasOwnProperty(elementType)) {
  27. if (JSONcontainer[elementType].redundant) {
  28. for (var i = 0; i < JSONcontainer[elementType].redundant.length; i++) {
  29. JSONcontainer[elementType].redundant[i].parentNode.removeChild(JSONcontainer[elementType].redundant[i]);
  30. }
  31. JSONcontainer[elementType].redundant = [];
  32. }
  33. }
  34. }
  35. };
  36. /**
  37. * Ensures that all elements are removed first up so they can be recreated cleanly
  38. * @param {Object} JSONcontainer
  39. */
  40. exports.resetElements = function(JSONcontainer) {
  41. exports.prepareElements(JSONcontainer);
  42. exports.cleanupElements(JSONcontainer);
  43. exports.prepareElements(JSONcontainer);
  44. };
  45. /**
  46. * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer
  47. * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this.
  48. *
  49. * @param {string} elementType
  50. * @param {Object} JSONcontainer
  51. * @param {Object} svgContainer
  52. * @returns {Element}
  53. * @private
  54. */
  55. exports.getSVGElement = function (elementType, JSONcontainer, svgContainer) {
  56. var element;
  57. // allocate SVG element, if it doesnt yet exist, create one.
  58. if (JSONcontainer.hasOwnProperty(elementType)) { // this element has been created before
  59. // check if there is an redundant element
  60. if (JSONcontainer[elementType].redundant.length > 0) {
  61. element = JSONcontainer[elementType].redundant[0];
  62. JSONcontainer[elementType].redundant.shift();
  63. }
  64. else {
  65. // create a new element and add it to the SVG
  66. element = document.createElementNS('http://www.w3.org/2000/svg', elementType);
  67. svgContainer.appendChild(element);
  68. }
  69. }
  70. else {
  71. // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it.
  72. element = document.createElementNS('http://www.w3.org/2000/svg', elementType);
  73. JSONcontainer[elementType] = {used: [], redundant: []};
  74. svgContainer.appendChild(element);
  75. }
  76. JSONcontainer[elementType].used.push(element);
  77. return element;
  78. };
  79. /**
  80. * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer
  81. * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this.
  82. *
  83. * @param {string} elementType
  84. * @param {Object} JSONcontainer
  85. * @param {Element} DOMContainer
  86. * @param {Element} insertBefore
  87. * @returns {*}
  88. */
  89. exports.getDOMElement = function (elementType, JSONcontainer, DOMContainer, insertBefore) {
  90. var element;
  91. // allocate DOM element, if it doesnt yet exist, create one.
  92. if (JSONcontainer.hasOwnProperty(elementType)) { // this element has been created before
  93. // check if there is an redundant element
  94. if (JSONcontainer[elementType].redundant.length > 0) {
  95. element = JSONcontainer[elementType].redundant[0];
  96. JSONcontainer[elementType].redundant.shift();
  97. }
  98. else {
  99. // create a new element and add it to the SVG
  100. element = document.createElement(elementType);
  101. if (insertBefore !== undefined) {
  102. DOMContainer.insertBefore(element, insertBefore);
  103. }
  104. else {
  105. DOMContainer.appendChild(element);
  106. }
  107. }
  108. }
  109. else {
  110. // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it.
  111. element = document.createElement(elementType);
  112. JSONcontainer[elementType] = {used: [], redundant: []};
  113. if (insertBefore !== undefined) {
  114. DOMContainer.insertBefore(element, insertBefore);
  115. }
  116. else {
  117. DOMContainer.appendChild(element);
  118. }
  119. }
  120. JSONcontainer[elementType].used.push(element);
  121. return element;
  122. };
  123. /**
  124. * Draw a point object. This is a separate function because it can also be called by the legend.
  125. * The reason the JSONcontainer and the target SVG svgContainer have to be supplied is so the legend can use these functions
  126. * as well.
  127. *
  128. * @param {number} x
  129. * @param {number} y
  130. * @param {Object} groupTemplate: A template containing the necessary information to draw the datapoint e.g., {style: 'circle', size: 5, className: 'className' }
  131. * @param {Object} JSONcontainer
  132. * @param {Object} svgContainer
  133. * @param {Object} labelObj
  134. * @returns {vis.PointItem}
  135. */
  136. exports.drawPoint = function(x, y, groupTemplate, JSONcontainer, svgContainer, labelObj) {
  137. var point;
  138. if (groupTemplate.style == 'circle') {
  139. point = exports.getSVGElement('circle', JSONcontainer, svgContainer);
  140. point.setAttributeNS(null, "cx", x);
  141. point.setAttributeNS(null, "cy", y);
  142. point.setAttributeNS(null, "r", 0.5 * groupTemplate.size);
  143. }
  144. else {
  145. point = exports.getSVGElement('rect', JSONcontainer, svgContainer);
  146. point.setAttributeNS(null, "x", x - 0.5 * groupTemplate.size);
  147. point.setAttributeNS(null, "y", y - 0.5 * groupTemplate.size);
  148. point.setAttributeNS(null, "width", groupTemplate.size);
  149. point.setAttributeNS(null, "height", groupTemplate.size);
  150. }
  151. if (groupTemplate.styles !== undefined) {
  152. point.setAttributeNS(null, "style", groupTemplate.styles);
  153. }
  154. point.setAttributeNS(null, "class", groupTemplate.className + " vis-point");
  155. //handle label
  156. if (labelObj) {
  157. var label = exports.getSVGElement('text', JSONcontainer, svgContainer);
  158. if (labelObj.xOffset) {
  159. x = x + labelObj.xOffset;
  160. }
  161. if (labelObj.yOffset) {
  162. y = y + labelObj.yOffset;
  163. }
  164. if (labelObj.content) {
  165. label.textContent = labelObj.content;
  166. }
  167. if (labelObj.className) {
  168. label.setAttributeNS(null, "class", labelObj.className + " vis-label");
  169. }
  170. label.setAttributeNS(null, "x", x);
  171. label.setAttributeNS(null, "y", y);
  172. }
  173. return point;
  174. };
  175. /**
  176. * draw a bar SVG element centered on the X coordinate
  177. *
  178. * @param {number} x
  179. * @param {number} y
  180. * @param {number} width
  181. * @param {number} height
  182. * @param {string} className
  183. * @param {Object} JSONcontainer
  184. * @param {Object} svgContainer
  185. * @param {string} style
  186. */
  187. exports.drawBar = function (x, y, width, height, className, JSONcontainer, svgContainer, style) {
  188. if (height != 0) {
  189. if (height < 0) {
  190. height *= -1;
  191. y -= height;
  192. }
  193. var rect = exports.getSVGElement('rect',JSONcontainer, svgContainer);
  194. rect.setAttributeNS(null, "x", x - 0.5 * width);
  195. rect.setAttributeNS(null, "y", y);
  196. rect.setAttributeNS(null, "width", width);
  197. rect.setAttributeNS(null, "height", height);
  198. rect.setAttributeNS(null, "class", className);
  199. if (style) {
  200. rect.setAttributeNS(null, "style", style);
  201. }
  202. }
  203. };