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.

170 lines
4.9 KiB

  1. import BezierEdgeBase from './util/BezierEdgeBase'
  2. class BezierEdgeStatic extends BezierEdgeBase {
  3. constructor(options, body, labelModule) {
  4. super(options, body, labelModule);
  5. }
  6. /**
  7. * Draw a line between two nodes
  8. * @param {CanvasRenderingContext2D} ctx
  9. * @private
  10. */
  11. _line(ctx, values, viaNode) {
  12. this._bezierCurve(ctx, values, viaNode);
  13. }
  14. getViaNode() {
  15. return this._getViaCoordinates();
  16. }
  17. /**
  18. * We do not use the to and fromPoints here to make the via nodes the same as edges without arrows.
  19. * @returns {{x: undefined, y: undefined}}
  20. * @private
  21. */
  22. _getViaCoordinates() {
  23. // Assumption: x/y coordinates in from/to always defined
  24. let xVia = undefined;
  25. let yVia = undefined;
  26. let factor = this.options.smooth.roundness;
  27. let type = this.options.smooth.type;
  28. let dx = Math.abs(this.from.x - this.to.x);
  29. let dy = Math.abs(this.from.y - this.to.y);
  30. if (type === 'discrete' || type === 'diagonalCross') {
  31. let stepX;
  32. let stepY;
  33. if (dx <= dy) {
  34. stepX = stepY = factor * dy;
  35. } else {
  36. stepX = stepY = factor * dx;
  37. }
  38. if (this.from.x > this.to.x) stepX = -stepX;
  39. if (this.from.y >= this.to.y) stepY = -stepY;
  40. xVia = this.from.x + stepX;
  41. yVia = this.from.y + stepY;
  42. if (type === "discrete") {
  43. if (dx <= dy) {
  44. xVia = dx < factor * dy ? this.from.x : xVia;
  45. } else {
  46. yVia = dy < factor * dx ? this.from.y : yVia;
  47. }
  48. }
  49. }
  50. else if (type === "straightCross") {
  51. let stepX = (1 - factor) * dx;
  52. let stepY = (1 - factor) * dy;
  53. if (dx <= dy) { // up - down
  54. stepX = 0;
  55. if (this.from.y < this.to.y) stepY = -stepY;
  56. }
  57. else { // left - right
  58. if (this.from.x < this.to.x) stepX = -stepX;
  59. stepY = 0;
  60. }
  61. xVia = this.to.x + stepX;
  62. yVia = this.to.y + stepY;
  63. }
  64. else if (type === 'horizontal') {
  65. let stepX = (1 - factor) * dx;
  66. if (this.from.x < this.to.x) stepX = -stepX;
  67. xVia = this.to.x + stepX;
  68. yVia = this.from.y;
  69. }
  70. else if (type === 'vertical') {
  71. let stepY = (1 - factor) * dy;
  72. if (this.from.y < this.to.y) stepY = -stepY;
  73. xVia = this.from.x;
  74. yVia = this.to.y + stepY;
  75. }
  76. else if (type === 'curvedCW') {
  77. dx = this.to.x - this.from.x;
  78. dy = this.from.y - this.to.y;
  79. let radius = Math.sqrt(dx * dx + dy * dy);
  80. let pi = Math.PI;
  81. let originalAngle = Math.atan2(dy, dx);
  82. let myAngle = (originalAngle + ((factor * 0.5) + 0.5) * pi) % (2 * pi);
  83. xVia = this.from.x + (factor * 0.5 + 0.5) * radius * Math.sin(myAngle);
  84. yVia = this.from.y + (factor * 0.5 + 0.5) * radius * Math.cos(myAngle);
  85. }
  86. else if (type === 'curvedCCW') {
  87. dx = this.to.x - this.from.x;
  88. dy = this.from.y - this.to.y;
  89. let radius = Math.sqrt(dx * dx + dy * dy);
  90. let pi = Math.PI;
  91. let originalAngle = Math.atan2(dy, dx);
  92. let myAngle = (originalAngle + ((-factor * 0.5) + 0.5) * pi) % (2 * pi);
  93. xVia = this.from.x + (factor * 0.5 + 0.5) * radius * Math.sin(myAngle);
  94. yVia = this.from.y + (factor * 0.5 + 0.5) * radius * Math.cos(myAngle);
  95. }
  96. else { // continuous
  97. let stepX;
  98. let stepY;
  99. if (dx <= dy) {
  100. stepX = stepY = factor * dy;
  101. } else {
  102. stepX = stepY = factor * dx;
  103. }
  104. if (this.from.x > this.to.x) stepX = -stepX;
  105. if (this.from.y >= this.to.y) stepY = -stepY;
  106. xVia = this.from.x + stepX;
  107. yVia = this.from.y + stepY;
  108. if (dx <= dy) {
  109. if (this.from.x <= this.to.x) {
  110. xVia = this.to.x < xVia ? this.to.x : xVia;
  111. }
  112. else {
  113. xVia = this.to.x > xVia ? this.to.x : xVia;
  114. }
  115. }
  116. else {
  117. if (this.from.y >= this.to.y) {
  118. yVia = this.to.y > yVia ? this.to.y : yVia;
  119. } else {
  120. yVia = this.to.y < yVia ? this.to.y : yVia;
  121. }
  122. }
  123. }
  124. return {x: xVia, y: yVia};
  125. }
  126. _findBorderPosition(nearNode, ctx, options = {}) {
  127. return this._findBorderPositionBezier(nearNode, ctx, options.via);
  128. }
  129. _getDistanceToEdge(x1, y1, x2, y2, x3, y3, viaNode = this._getViaCoordinates()) { // x3,y3 is the point
  130. return this._getDistanceToBezierEdge(x1, y1, x2, y2, x3, y3, viaNode);
  131. }
  132. /**
  133. * Combined function of pointOnLine and pointOnBezier. This gives the coordinates of a point on the line at a certain percentage of the way
  134. * @param percentage
  135. * @param viaNode
  136. * @returns {{x: number, y: number}}
  137. * @private
  138. */
  139. getPoint(percentage, viaNode = this._getViaCoordinates()) {
  140. var t = percentage;
  141. var x = Math.pow(1 - t, 2) * this.fromPoint.x + (2 * t * (1 - t)) * viaNode.x + Math.pow(t, 2) * this.toPoint.x;
  142. var y = Math.pow(1 - t, 2) * this.fromPoint.y + (2 * t * (1 - t)) * viaNode.y + Math.pow(t, 2) * this.toPoint.y;
  143. return {x: x, y: y};
  144. }
  145. }
  146. export default BezierEdgeStatic;