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.6 KiB

  1. var util = require('../../util');
  2. var DOMutil = require('../../DOMutil');
  3. /**
  4. * /**
  5. * @param {object} group | the object of the group from the dataset
  6. * @param {string} groupId | ID of the group
  7. * @param {object} options | the default options
  8. * @param {array} groupsUsingDefaultStyles | this array has one entree.
  9. * It is passed as an array so it is passed by reference.
  10. * It enumerates through the default styles
  11. * @constructor
  12. */
  13. function GraphGroup(group, groupId, options, groupsUsingDefaultStyles) {
  14. this.id = groupId;
  15. var fields = ['sampling', 'style', 'sort', 'yAxisOrientation', 'barChart', 'drawPoints', 'shaded', 'interpolation'];
  16. this.options = util.selectiveBridgeObject(fields, options);
  17. this.usingDefaultStyle = group.className === undefined;
  18. this.groupsUsingDefaultStyles = groupsUsingDefaultStyles;
  19. this.zeroPosition = 0;
  20. this.update(group);
  21. if (this.usingDefaultStyle == true) {
  22. this.groupsUsingDefaultStyles[0] += 1;
  23. }
  24. this.itemsData = [];
  25. this.visible = group.visible === undefined ? true : group.visible;
  26. }
  27. function insertionSort (a,compare) {
  28. for (var i = 0; i < a.length; i++) {
  29. var k = a[i];
  30. for (var j = i; j > 0 && compare(k,a[j - 1])<0; j--) {
  31. a[j] = a[j - 1];
  32. }
  33. a[j] = k;
  34. }
  35. return a;
  36. }
  37. /**
  38. * this loads a reference to all items in this group into this group.
  39. * @param {array} items
  40. */
  41. GraphGroup.prototype.setItems = function (items) {
  42. if (items != null) {
  43. this.itemsData = items;
  44. if (this.options.sort == true) {
  45. insertionSort(this.itemsData,function (a, b) {
  46. return a.x > b.x ? 1 : -1;
  47. });
  48. }
  49. }
  50. else {
  51. this.itemsData = [];
  52. }
  53. };
  54. GraphGroup.prototype.getItems = function () {
  55. return this.itemsData;
  56. }
  57. /**
  58. * this is used for barcharts and shading, this way, we only have to calculate it once.
  59. * @param pos
  60. */
  61. GraphGroup.prototype.setZeroPosition = function (pos) {
  62. this.zeroPosition = pos;
  63. };
  64. /**
  65. * set the options of the graph group over the default options.
  66. * @param options
  67. */
  68. GraphGroup.prototype.setOptions = function (options) {
  69. if (options !== undefined) {
  70. var fields = ['sampling', 'style', 'sort', 'yAxisOrientation', 'barChart', 'excludeFromLegend', 'excludeFromStacking'];
  71. util.selectiveDeepExtend(fields, this.options, options);
  72. // if the group's drawPoints is a function delegate the callback to the onRender property
  73. if (typeof options.drawPoints == 'function') {
  74. options.drawPoints = {
  75. onRender: options.drawPoints
  76. }
  77. }
  78. util.mergeOptions(this.options, options, 'interpolation');
  79. util.mergeOptions(this.options, options, 'drawPoints');
  80. util.mergeOptions(this.options, options, 'shaded');
  81. if (options.interpolation) {
  82. if (typeof options.interpolation == 'object') {
  83. if (options.interpolation.parametrization) {
  84. if (options.interpolation.parametrization == 'uniform') {
  85. this.options.interpolation.alpha = 0;
  86. }
  87. else if (options.interpolation.parametrization == 'chordal') {
  88. this.options.interpolation.alpha = 1.0;
  89. }
  90. else {
  91. this.options.interpolation.parametrization = 'centripetal';
  92. this.options.interpolation.alpha = 0.5;
  93. }
  94. }
  95. }
  96. }
  97. }
  98. };
  99. /**
  100. * this updates the current group class with the latest group dataset entree, used in _updateGroup in linegraph
  101. * @param group
  102. */
  103. GraphGroup.prototype.update = function (group) {
  104. this.group = group;
  105. this.content = group.content || 'graph';
  106. this.className = group.className || this.className || 'vis-graph-group' + this.groupsUsingDefaultStyles[0] % 10;
  107. this.visible = group.visible === undefined ? true : group.visible;
  108. this.style = group.style;
  109. this.setOptions(group.options);
  110. };
  111. //TODO: move these render functions into the type specific files and call them from LineGraph
  112. /**
  113. * draw the icon for the legend.
  114. *
  115. * @param x
  116. * @param y
  117. * @param JSONcontainer
  118. * @param SVGcontainer
  119. * @param iconWidth
  120. * @param iconHeight
  121. */
  122. GraphGroup.prototype.drawIcon = function (x, y, JSONcontainer, SVGcontainer, iconWidth, iconHeight) {
  123. var fillHeight = iconHeight * 0.5;
  124. var path, fillPath;
  125. var outline = DOMutil.getSVGElement("rect", JSONcontainer, SVGcontainer);
  126. outline.setAttributeNS(null, "x", x);
  127. outline.setAttributeNS(null, "y", y - fillHeight);
  128. outline.setAttributeNS(null, "width", iconWidth);
  129. outline.setAttributeNS(null, "height", 2 * fillHeight);
  130. outline.setAttributeNS(null, "class", "vis-outline");
  131. if (this.options.style == 'line') {
  132. path = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer);
  133. path.setAttributeNS(null, "class", this.className);
  134. if (this.style !== undefined) {
  135. path.setAttributeNS(null, "style", this.style);
  136. }
  137. path.setAttributeNS(null, "d", "M" + x + "," + y + " L" + (x + iconWidth) + "," + y + "");
  138. if (this.options.shaded.enabled == true) {
  139. fillPath = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer);
  140. if (this.options.shaded.orientation == 'top') {
  141. fillPath.setAttributeNS(null, "d", "M" + x + ", " + (y - fillHeight) +
  142. "L" + x + "," + y + " L" + (x + iconWidth) + "," + y + " L" + (x + iconWidth) + "," + (y - fillHeight));
  143. }
  144. else {
  145. fillPath.setAttributeNS(null, "d", "M" + x + "," + y + " " +
  146. "L" + x + "," + (y + fillHeight) + " " +
  147. "L" + (x + iconWidth) + "," + (y + fillHeight) +
  148. "L" + (x + iconWidth) + "," + y);
  149. }
  150. fillPath.setAttributeNS(null, "class", this.className + " vis-icon-fill");
  151. if (this.options.shaded.style !== undefined && this.options.shaded.style !== "") {
  152. fillPath.setAttributeNS(null, "style", this.options.shaded.style);
  153. }
  154. }
  155. if (this.options.drawPoints.enabled == true) {
  156. var groupTemplate = {
  157. style: this.options.drawPoints.style,
  158. styles: this.options.drawPoints.styles,
  159. size: this.options.drawPoints.size,
  160. className: this.className
  161. };
  162. DOMutil.drawPoint(x + 0.5 * iconWidth, y, groupTemplate, JSONcontainer, SVGcontainer);
  163. }
  164. }
  165. else {
  166. var barWidth = Math.round(0.3 * iconWidth);
  167. var bar1Height = Math.round(0.4 * iconHeight);
  168. var bar2Height = Math.round(0.75 * iconHeight);
  169. var offset = Math.round((iconWidth - (2 * barWidth)) / 3);
  170. DOMutil.drawBar(x + 0.5 * barWidth + offset, y + fillHeight - bar1Height - 1, barWidth, bar1Height, this.className + ' vis-bar', JSONcontainer, SVGcontainer, this.style);
  171. DOMutil.drawBar(x + 1.5 * barWidth + offset + 2, y + fillHeight - bar2Height - 1, barWidth, bar2Height, this.className + ' vis-bar', JSONcontainer, SVGcontainer, this.style);
  172. }
  173. };
  174. /**
  175. * return the legend entree for this group.
  176. *
  177. * @param iconWidth
  178. * @param iconHeight
  179. * @returns {{icon: HTMLElement, label: (group.content|*|string), orientation: (.options.yAxisOrientation|*)}}
  180. */
  181. GraphGroup.prototype.getLegend = function (iconWidth, iconHeight) {
  182. var svg = document.createElementNS('http://www.w3.org/2000/svg', "svg");
  183. this.drawIcon(0, 0.5 * iconHeight, [], svg, iconWidth, iconHeight);
  184. return {icon: svg, label: this.content, orientation: this.options.yAxisOrientation};
  185. };
  186. GraphGroup.prototype.getYRange = function (groupData) {
  187. var yMin = groupData[0].y;
  188. var yMax = groupData[0].y;
  189. for (var j = 0; j < groupData.length; j++) {
  190. yMin = yMin > groupData[j].y ? groupData[j].y : yMin;
  191. yMax = yMax < groupData[j].y ? groupData[j].y : yMax;
  192. }
  193. return {min: yMin, max: yMax, yAxisOrientation: this.options.yAxisOrientation};
  194. };
  195. module.exports = GraphGroup;