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.

233 lines
6.2 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. var Emitter = require('emitter-component');
  2. var Hammer = require('../module/hammer');
  3. var util = require('../util');
  4. var DataSet = require('../DataSet');
  5. var DataView = require('../DataView');
  6. var Range = require('./Range');
  7. var Core = require('./Core');
  8. var TimeAxis = require('./component/TimeAxis');
  9. var CurrentTime = require('./component/CurrentTime');
  10. var CustomTime = require('./component/CustomTime');
  11. var LineGraph = require('./component/LineGraph');
  12. /**
  13. * Create a timeline visualization
  14. * @param {HTMLElement} container
  15. * @param {vis.DataSet | Array | google.visualization.DataTable} [items]
  16. * @param {Object} [options] See Graph2d.setOptions for the available options.
  17. * @constructor
  18. * @extends Core
  19. */
  20. function Graph2d (container, items, options, groups) {
  21. var me = this;
  22. this.defaultOptions = {
  23. start: null,
  24. end: null,
  25. autoResize: true,
  26. orientation: 'bottom',
  27. width: null,
  28. height: null,
  29. maxHeight: null,
  30. minHeight: null
  31. };
  32. this.options = util.deepExtend({}, this.defaultOptions);
  33. // Create the DOM, props, and emitter
  34. this._create(container);
  35. // all components listed here will be repainted automatically
  36. this.components = [];
  37. this.body = {
  38. dom: this.dom,
  39. domProps: this.props,
  40. emitter: {
  41. on: this.on.bind(this),
  42. off: this.off.bind(this),
  43. emit: this.emit.bind(this)
  44. },
  45. util: {
  46. snap: null, // will be specified after TimeAxis is created
  47. toScreen: me._toScreen.bind(me),
  48. toGlobalScreen: me._toGlobalScreen.bind(me), // this refers to the root.width
  49. toTime: me._toTime.bind(me),
  50. toGlobalTime : me._toGlobalTime.bind(me)
  51. }
  52. };
  53. // range
  54. this.range = new Range(this.body);
  55. this.components.push(this.range);
  56. this.body.range = this.range;
  57. // time axis
  58. this.timeAxis = new TimeAxis(this.body);
  59. this.components.push(this.timeAxis);
  60. this.body.util.snap = this.timeAxis.snap.bind(this.timeAxis);
  61. // current time bar
  62. this.currentTime = new CurrentTime(this.body);
  63. this.components.push(this.currentTime);
  64. // custom time bar
  65. // Note: time bar will be attached in this.setOptions when selected
  66. this.customTime = new CustomTime(this.body);
  67. this.components.push(this.customTime);
  68. // item set
  69. this.linegraph = new LineGraph(this.body);
  70. this.components.push(this.linegraph);
  71. this.itemsData = null; // DataSet
  72. this.groupsData = null; // DataSet
  73. // apply options
  74. if (options) {
  75. this.setOptions(options);
  76. }
  77. // IMPORTANT: THIS HAPPENS BEFORE SET ITEMS!
  78. if (groups) {
  79. this.setGroups(groups);
  80. }
  81. // create itemset
  82. if (items) {
  83. this.setItems(items);
  84. }
  85. else {
  86. this.redraw();
  87. }
  88. }
  89. // Extend the functionality from Core
  90. Graph2d.prototype = new Core();
  91. /**
  92. * Set items
  93. * @param {vis.DataSet | Array | google.visualization.DataTable | null} items
  94. */
  95. Graph2d.prototype.setItems = function(items) {
  96. var initialLoad = (this.itemsData == null);
  97. // convert to type DataSet when needed
  98. var newDataSet;
  99. if (!items) {
  100. newDataSet = null;
  101. }
  102. else if (items instanceof DataSet || items instanceof DataView) {
  103. newDataSet = items;
  104. }
  105. else {
  106. // turn an array into a dataset
  107. newDataSet = new DataSet(items, {
  108. type: {
  109. start: 'Date',
  110. end: 'Date'
  111. }
  112. });
  113. }
  114. // set items
  115. this.itemsData = newDataSet;
  116. this.linegraph && this.linegraph.setItems(newDataSet);
  117. if (initialLoad && ('start' in this.options || 'end' in this.options)) {
  118. this.fit();
  119. var start = ('start' in this.options) ? util.convert(this.options.start, 'Date') : null;
  120. var end = ('end' in this.options) ? util.convert(this.options.end, 'Date') : null;
  121. this.setWindow(start, end);
  122. }
  123. };
  124. /**
  125. * Set groups
  126. * @param {vis.DataSet | Array | google.visualization.DataTable} groups
  127. */
  128. Graph2d.prototype.setGroups = function(groups) {
  129. // convert to type DataSet when needed
  130. var newDataSet;
  131. if (!groups) {
  132. newDataSet = null;
  133. }
  134. else if (groups instanceof DataSet || groups instanceof DataView) {
  135. newDataSet = groups;
  136. }
  137. else {
  138. // turn an array into a dataset
  139. newDataSet = new DataSet(groups);
  140. }
  141. this.groupsData = newDataSet;
  142. this.linegraph.setGroups(newDataSet);
  143. };
  144. /**
  145. * Returns an object containing an SVG element with the icon of the group (size determined by iconWidth and iconHeight), the label of the group (content) and the yAxisOrientation of the group (left or right).
  146. * @param groupId
  147. * @param width
  148. * @param height
  149. */
  150. Graph2d.prototype.getLegend = function(groupId, width, height) {
  151. if (width === undefined) {width = 15;}
  152. if (height === undefined) {height = 15;}
  153. if (this.linegraph.groups[groupId] !== undefined) {
  154. return this.linegraph.groups[groupId].getLegend(width,height);
  155. }
  156. else {
  157. return "cannot find group:" + groupId;
  158. }
  159. }
  160. /**
  161. * This checks if the visible option of the supplied group (by ID) is true or false.
  162. * @param groupId
  163. * @returns {*}
  164. */
  165. Graph2d.prototype.isGroupVisible = function(groupId) {
  166. if (this.linegraph.groups[groupId] !== undefined) {
  167. return (this.linegraph.groups[groupId].visible && (this.linegraph.options.groups.visibility[groupId] === undefined || this.linegraph.options.groups.visibility[groupId] == true));
  168. }
  169. else {
  170. return false;
  171. }
  172. }
  173. /**
  174. * Get the data range of the item set.
  175. * @returns {{min: Date, max: Date}} range A range with a start and end Date.
  176. * When no minimum is found, min==null
  177. * When no maximum is found, max==null
  178. */
  179. Graph2d.prototype.getItemRange = function() {
  180. var min = null;
  181. var max = null;
  182. // calculate min from start filed
  183. for (var groupId in this.linegraph.groups) {
  184. if (this.linegraph.groups.hasOwnProperty(groupId)) {
  185. if (this.linegraph.groups[groupId].visible == true) {
  186. for (var i = 0; i < this.linegraph.groups[groupId].itemsData.length; i++) {
  187. var item = this.linegraph.groups[groupId].itemsData[i];
  188. var value = util.convert(item.x, 'Date').valueOf();
  189. min = min == null ? value : min > value ? value : min;
  190. max = max == null ? value : max < value ? value : max;
  191. }
  192. }
  193. }
  194. }
  195. return {
  196. min: (min != null) ? new Date(min) : null,
  197. max: (max != null) ? new Date(max) : null
  198. };
  199. };
  200. module.exports = Graph2d;