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.

177 lines
4.1 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 be contained within this module.
  13. * All classes here except `EndPoints` should be considered as private to this module.
  14. */
  15. // NOTE: When a typedef is isolated in a separate comment block, an actual description is generated for it,
  16. // using the rest of the commenting in the code block. Usage of typedef in other comments then
  17. // link to there. TIL.
  18. //
  19. // Also noteworthy, all typedef's set up in this manner are collected in a single, global page 'global.html'.
  20. // In other words, it doesn't matter *where* the typedef's are defined in the code.
  21. //
  22. //
  23. // TODO: add descriptive commenting to given typedef's
  24. /**
  25. * @typedef {{type:string, point:Point, angle:number, length:number}} ArrowData
  26. *
  27. * Object containing instantiation data for a given endpoint.
  28. */
  29. /**
  30. * @typedef {{x:number, y:number}} Point
  31. *
  32. * A point in view-coordinates.
  33. */
  34. /**
  35. * Common methods for endpoints
  36. *
  37. * @class
  38. */
  39. class EndPoint {
  40. /**
  41. * Apply transformation on points for display.
  42. *
  43. * The following is done:
  44. * - rotate by the specified angle
  45. * - multiply the (normalized) coordinates by the passed length
  46. * - offset by the target coordinates
  47. *
  48. * @param {Array<Point>} points
  49. * @param {ArrowData} arrowData
  50. * @static
  51. */
  52. static transform(points, arrowData) {
  53. if (!(points instanceof Array)) {
  54. points = [points];
  55. }
  56. var x = arrowData.point.x;
  57. var y = arrowData.point.y;
  58. var angle = arrowData.angle
  59. var length = arrowData.length;
  60. for(var i = 0; i < points.length; ++i) {
  61. var p = points[i];
  62. var xt = p.x * Math.cos(angle) - p.y * Math.sin(angle);
  63. var yt = p.x * Math.sin(angle) + p.y * Math.cos(angle);
  64. p.x = x + length*xt;
  65. p.y = y + length*yt;
  66. }
  67. }
  68. /**
  69. * Draw a closed path using the given real coordinates.
  70. *
  71. * @param {CanvasRenderingContext2D} ctx
  72. * @param {Array.<Point>} points
  73. * @static
  74. */
  75. static drawPath(ctx, points) {
  76. ctx.beginPath();
  77. ctx.moveTo(points[0].x, points[0].y);
  78. for(var i = 1; i < points.length; ++i) {
  79. ctx.lineTo(points[i].x, points[i].y);
  80. }
  81. ctx.closePath();
  82. }
  83. }
  84. /**
  85. * Drawing methods for the arrow endpoint.
  86. * @extends EndPoint
  87. */
  88. class Arrow extends EndPoint {
  89. /**
  90. * Draw this shape at the end of a line.
  91. *
  92. * @param {CanvasRenderingContext2D} ctx
  93. * @param {ArrowData} arrowData
  94. * @static
  95. */
  96. static draw(ctx, arrowData) {
  97. // Normalized points of closed path, in the order that they should be drawn.
  98. // (0, 0) is the attachment point, and the point around which should be rotated
  99. var points = [
  100. { x: 0 , y: 0 },
  101. { x:-1 , y: 0.3},
  102. { x:-0.9, y: 0 },
  103. { x:-1 , y:-0.3},
  104. ];
  105. EndPoint.transform(points, arrowData);
  106. EndPoint.drawPath(ctx, points);
  107. }
  108. }
  109. /**
  110. * Drawing methods for the circle endpoint.
  111. */
  112. class Circle {
  113. /**
  114. * Draw this shape at the end of a line.
  115. *
  116. * @param {CanvasRenderingContext2D} ctx
  117. * @param {ArrowData} arrowData
  118. * @static
  119. */
  120. static draw(ctx, arrowData) {
  121. var point = {x:-0.4, y:0};
  122. EndPoint.transform(point, arrowData);
  123. ctx.circle(point.x, point.y, arrowData.length*0.4);
  124. }
  125. }
  126. /**
  127. * Drawing methods for the endpoints.
  128. */
  129. class EndPoints {
  130. /**
  131. * Draw an endpoint
  132. *
  133. * @param {CanvasRenderingContext2D} ctx
  134. * @param {ArrowData} arrowData
  135. * @static
  136. */
  137. static draw(ctx, arrowData) {
  138. var type;
  139. if (arrowData.type) {
  140. type = arrowData.type.toLowerCase();
  141. }
  142. switch (type) {
  143. case 'circle':
  144. Circle.draw(ctx, arrowData);
  145. break;
  146. case 'arrow': // fall-through
  147. default:
  148. Arrow.draw(ctx, arrowData);
  149. }
  150. }
  151. }
  152. export default EndPoints;