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.

241 lines
5.5 KiB

  1. /**
  2. * Created by Alex on 3/4/2015.
  3. */
  4. var util = require("../../util");
  5. var DataSet = require('../../DataSet');
  6. var DataView = require('../../DataView');
  7. var Edge = require("./components/Edge");
  8. class EdgesHandler {
  9. constructor(body, images, groups) {
  10. this.body = body;
  11. this.images = images;
  12. this.groups = groups;
  13. // create the edge API in the body container
  14. this.body.functions.createEdge = this.create.bind(this);
  15. this.edgesListeners = {
  16. 'add': (event, params) => {this.add(params.items);},
  17. 'update': (event, params) => {this.update(params.items);},
  18. 'remove': (event, params) => {this.remove(params.items);}
  19. };
  20. this.options = {};
  21. this.defaultOptions = {
  22. arrows: {
  23. to: {enabled: false, scaleFactor:1}, // boolean / {arrowScaleFactor:1} / {enabled: false, arrowScaleFactor:1}
  24. middle: {enabled: false, scaleFactor:1},
  25. from: {enabled: false, scaleFactor:1}
  26. },
  27. color: {
  28. color:'#848484',
  29. highlight:'#848484',
  30. hover: '#848484',
  31. inherit: {
  32. enabled: true,
  33. source: 'from', // from / true
  34. useGradients: false // release in 4.0
  35. },
  36. opacity:1.0
  37. },
  38. dashes:{
  39. enabled: false,
  40. preset: 'dotted',
  41. length: 10,
  42. gap: 5,
  43. altLength: undefined
  44. },
  45. font: {
  46. color: '#343434',
  47. size: 14, // px
  48. face: 'arial',
  49. background: 'none',
  50. stroke: 1, // px
  51. strokeColor: 'white',
  52. align:'horizontal'
  53. },
  54. hidden: false,
  55. hoverWidth: 1.5,
  56. label: undefined,
  57. length: undefined,
  58. physics: true,
  59. scaling:{
  60. min: 1,
  61. max: 15,
  62. label: {
  63. enabled: true,
  64. min: 14,
  65. max: 30,
  66. maxVisible: 30,
  67. drawThreshold: 3
  68. },
  69. customScalingFunction: function (min,max,total,value) {
  70. if (max == min) {
  71. return 0.5;
  72. }
  73. else {
  74. var scale = 1 / (max - min);
  75. return Math.max(0,(value - min)*scale);
  76. }
  77. }
  78. },
  79. selfReferenceSize:20,
  80. smooth: {
  81. enabled: true,
  82. dynamic: true,
  83. type: "continuous",
  84. roundness: 0.5
  85. },
  86. title:undefined,
  87. width: 1,
  88. widthSelectionMultiplier: 2,
  89. value:1
  90. };
  91. util.extend(this.options, this.defaultOptions);
  92. }
  93. setOptions(options) {
  94. }
  95. /**
  96. * Load edges by reading the data table
  97. * @param {Array | DataSet | DataView} edges The data containing the edges.
  98. * @private
  99. * @private
  100. */
  101. setData(edges) {
  102. var oldEdgesData = this.body.data.edges;
  103. if (edges instanceof DataSet || edges instanceof DataView) {
  104. this.body.data.edges = edges;
  105. }
  106. else if (Array.isArray(edges)) {
  107. this.body.data.edges = new DataSet();
  108. this.body.data.edges.add(edges);
  109. }
  110. else if (!edges) {
  111. this.body.data.edges = new DataSet();
  112. }
  113. else {
  114. throw new TypeError('Array or DataSet expected');
  115. }
  116. // TODO: is this null or undefined or false?
  117. if (oldEdgesData) {
  118. // unsubscribe from old dataset
  119. util.forEach(this.edgesListeners, (callback, event) => {oldEdgesData.off(event, callback);});
  120. }
  121. // remove drawn edges
  122. this.body.edges = {};
  123. // TODO: is this null or undefined or false?
  124. if (this.body.data.edges) {
  125. // subscribe to new dataset
  126. util.forEach(this.edgesListeners, (callback, event) => {this.body.data.edges.on(event, callback);});
  127. // draw all new nodes
  128. var ids = this.body.data.edges.getIds();
  129. this.add(ids);
  130. }
  131. this.body.emitter.emit("_dataChanged");
  132. }
  133. /**
  134. * Add edges
  135. * @param {Number[] | String[]} ids
  136. * @private
  137. */
  138. add(ids) {
  139. var edges = this.body.edges;
  140. var edgesData = this.body.data.edges;
  141. for (let i = 0; i < ids.length; i++) {
  142. var id = ids[i];
  143. var oldEdge = edges[id];
  144. if (oldEdge) {
  145. oldEdge.disconnect();
  146. }
  147. var data = edgesData.get(id, {"showInternalIds" : true});
  148. edges[id] = this.create(data);
  149. }
  150. this.body.emitter.emit("_dataChanged");
  151. }
  152. /**
  153. * Update existing edges, or create them when not yet existing
  154. * @param {Number[] | String[]} ids
  155. * @private
  156. */
  157. update(ids) {
  158. var edges = this.body.edges;
  159. var edgesData = this.body.data.edges;
  160. var dataChanged = false;
  161. for (var i = 0; i < ids.length; i++) {
  162. var id = ids[i];
  163. var data = edgesData.get(id);
  164. var edge = edges[id];
  165. if (edge === null) {
  166. // update edge
  167. edge.disconnect();
  168. edge.setOptions(data);
  169. edge.connect();
  170. }
  171. else {
  172. // create edge
  173. this.body.edges[id] = this.create(data);
  174. dataChanged = true;
  175. }
  176. }
  177. if (dataChanged === true) {
  178. this.body.emitter.emit("_dataChanged");
  179. }
  180. else {
  181. this.body.emitter.emit("_dataUpdated");
  182. }
  183. }
  184. /**
  185. * Remove existing edges. Non existing ids will be ignored
  186. * @param {Number[] | String[]} ids
  187. * @private
  188. */
  189. remove(ids) {
  190. var edges = this.body.edges;
  191. for (var i = 0; i < ids.length; i++) {
  192. var id = ids[i];
  193. var edge = edges[id];
  194. if (edge !== undefined) {
  195. if (edge.via != null) {
  196. delete this.body.supportNodes[edge.via.id];
  197. }
  198. edge.disconnect();
  199. delete edges[id];
  200. }
  201. }
  202. this.body.emitter.emit("_dataChanged");
  203. }
  204. create(properties) {
  205. return new Edge(properties, this.body, this.options)
  206. }
  207. }
  208. export default EdgesHandler;