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.

204 lines
6.7 KiB

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