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.

209 lines
4.7 KiB

  1. /** ============================================================================
  2. * Location of all the endpoint drawing routines.
  3. *
  4. * Every endpoint has its own drawing routine, which contains an endpoint definition.
  5. *
  6. * The endpoint definitions must have the following properies:
  7. *
  8. * - (0,0) is the connection point to the node it attaches to
  9. * - The endpoints are orientated to the positive x-direction
  10. * - The length of the endpoint is at most 1
  11. *
  12. * As long as the endpoint classes remain simple and not too numerous, they will
  13. * be contained within this module.
  14. * All classes here except `EndPoints` should be considered as private to this module.
  15. *
  16. * -----------------------------------------------------------------------------
  17. * ### Further Actions
  18. *
  19. * After adding a new endpoint here, you also need to do the following things:
  20. *
  21. * - Add the new endpoint name to `network/options.js` in array `endPoints`.
  22. * - Add the new endpoint name to the documentation.
  23. * Scan for 'arrows.to.type` and add it to the description.
  24. * - Add the endpoint to the examples. At the very least, add it to example
  25. * `edgeStyles/arrowTypes`.
  26. * ============================================================================= */
  27. /**
  28. * Common methods for endpoints
  29. *
  30. * @class
  31. */
  32. class EndPoint {
  33. /**
  34. * Apply transformation on points for display.
  35. *
  36. * The following is done:
  37. * - rotate by the specified angle
  38. * - multiply the (normalized) coordinates by the passed length
  39. * - offset by the target coordinates
  40. *
  41. * @param {Array<Point>} points
  42. * @param {ArrowData} arrowData
  43. * @static
  44. */
  45. static transform(points, arrowData) {
  46. if (!(points instanceof Array)) {
  47. points = [points];
  48. }
  49. var x = arrowData.point.x;
  50. var y = arrowData.point.y;
  51. var angle = arrowData.angle
  52. var length = arrowData.length;
  53. for(var i = 0; i < points.length; ++i) {
  54. var p = points[i];
  55. var xt = p.x * Math.cos(angle) - p.y * Math.sin(angle);
  56. var yt = p.x * Math.sin(angle) + p.y * Math.cos(angle);
  57. p.x = x + length*xt;
  58. p.y = y + length*yt;
  59. }
  60. }
  61. /**
  62. * Draw a closed path using the given real coordinates.
  63. *
  64. * @param {CanvasRenderingContext2D} ctx
  65. * @param {Array.<Point>} points
  66. * @static
  67. */
  68. static drawPath(ctx, points) {
  69. ctx.beginPath();
  70. ctx.moveTo(points[0].x, points[0].y);
  71. for(var i = 1; i < points.length; ++i) {
  72. ctx.lineTo(points[i].x, points[i].y);
  73. }
  74. ctx.closePath();
  75. }
  76. }
  77. /**
  78. * Drawing methods for the arrow endpoint.
  79. * @extends EndPoint
  80. */
  81. class Arrow extends EndPoint {
  82. /**
  83. * Draw this shape at the end of a line.
  84. *
  85. * @param {CanvasRenderingContext2D} ctx
  86. * @param {ArrowData} arrowData
  87. * @static
  88. */
  89. static draw(ctx, arrowData) {
  90. // Normalized points of closed path, in the order that they should be drawn.
  91. // (0, 0) is the attachment point, and the point around which should be rotated
  92. var points = [
  93. { x: 0 , y: 0 },
  94. { x:-1 , y: 0.3},
  95. { x:-0.9, y: 0 },
  96. { x:-1 , y:-0.3},
  97. ];
  98. EndPoint.transform(points, arrowData);
  99. EndPoint.drawPath(ctx, points);
  100. }
  101. }
  102. /**
  103. * Drawing methods for the circle endpoint.
  104. */
  105. class Circle {
  106. /**
  107. * Draw this shape at the end of a line.
  108. *
  109. * @param {CanvasRenderingContext2D} ctx
  110. * @param {ArrowData} arrowData
  111. * @static
  112. */
  113. static draw(ctx, arrowData) {
  114. var point = {x:-0.4, y:0};
  115. EndPoint.transform(point, arrowData);
  116. ctx.circle(point.x, point.y, arrowData.length*0.4);
  117. }
  118. }
  119. /**
  120. * Drawing methods for the bar endpoint.
  121. */
  122. class Bar {
  123. /**
  124. * Draw this shape at the end of a line.
  125. *
  126. * @param {CanvasRenderingContext2D} ctx
  127. * @param {ArrowData} arrowData
  128. * @static
  129. */
  130. static draw(ctx, arrowData) {
  131. /*
  132. var points = [
  133. {x:0, y:0.5},
  134. {x:0, y:-0.5}
  135. ];
  136. EndPoint.transform(points, arrowData);
  137. ctx.beginPath();
  138. ctx.moveTo(points[0].x, points[0].y);
  139. ctx.lineTo(points[1].x, points[1].y);
  140. ctx.stroke();
  141. */
  142. var points = [
  143. {x:0, y:0.5},
  144. {x:0, y:-0.5},
  145. {x:-0.15, y:-0.5},
  146. {x:-0.15, y:0.5},
  147. ];
  148. EndPoint.transform(points, arrowData);
  149. EndPoint.drawPath(ctx, points);
  150. }
  151. }
  152. /**
  153. * Drawing methods for the endpoints.
  154. */
  155. class EndPoints {
  156. /**
  157. * Draw an endpoint
  158. *
  159. * @param {CanvasRenderingContext2D} ctx
  160. * @param {ArrowData} arrowData
  161. * @static
  162. */
  163. static draw(ctx, arrowData) {
  164. var type;
  165. if (arrowData.type) {
  166. type = arrowData.type.toLowerCase();
  167. }
  168. switch (type) {
  169. case 'circle':
  170. Circle.draw(ctx, arrowData);
  171. break;
  172. case 'bar':
  173. Bar.draw(ctx, arrowData);
  174. break;
  175. case 'arrow': // fall-through
  176. default:
  177. Arrow.draw(ctx, arrowData);
  178. }
  179. }
  180. }
  181. export default EndPoints;