Source: js/path/line.js

  1. /**
  2. * Line.
  3. * @class
  4. * @param {?object} [data] JSON data.
  5. * @param {?number} [data.loopStart=180] Loop start angle in degrees.
  6. * @param {?number} [data.loopEnd=270] Loop end angle in degrees.
  7. * @param {?boolean} [data.arrow=false]
  8. * @param {?number} [data.arrowLength=10]
  9. * @param {?number} [data.arrowAngle=15]
  10. */
  11. ge.path.Line = function Line(data) {
  12. ge.path.Path.call(this, data);
  13. this.arrow = !!data.arrow;
  14. this.arrowLength = +data.arrowLength || 10;
  15. this.arrowAngle = new ge.Angle(+data.arrowAngle || 15);
  16. this.arrowAngle2 = new ge.Angle(-data.arrowAngle || -15);
  17. };
  18. ge.path.Line.prototype = Object.create(ge.path.Line);
  19. Object.defineProperty(
  20. ge.path.Line.prototype,
  21. 'constructor',
  22. {
  23. value: ge.path.Line,
  24. enumerable: false,
  25. writable: true
  26. }
  27. );
  28. ge.path.addClass(ge.path.Line);
  29. /**
  30. * Return arrow path.
  31. * @param {ge.Point} src Link source.
  32. * @param {ge.Point} dst Link target.
  33. * @returns {string} SVG path.
  34. */
  35. ge.path.Line.prototype.arrowPath = function arrow(src, dst) {
  36. var b = src.clone().sub(dst).normalize();
  37. var c = b.clone().rotate(this.arrowAngle2).mul(this.arrowLength).add(dst);
  38. b.rotate(this.arrowAngle).mul(this.arrowLength).add(dst);
  39. return 'M'.concat(
  40. dst.x, ',', dst.y,
  41. 'L', b.x, ',', b.y,
  42. 'L', c.x, ',', c.y,
  43. 'Z'
  44. );
  45. };
  46. /**
  47. * Return text path and set link path.
  48. * @param {ge.Link} link Link data.
  49. * @returns {string} SVG path.
  50. */
  51. ge.path.Line.prototype.path = function path(link) {
  52. var src, dst;
  53. if(link.source === link.target) {
  54. src = link.source.shape.getPoint(link.source, this.loopStart);
  55. dst = link.source.shape.getPoint(link.source, this.loopEnd);
  56. var rx = link.source.width / 2;
  57. var ry = link.source.height / 2;
  58. link.reversed = false;
  59. link.path = 'M'.concat(
  60. src.x, ',', src.y,
  61. 'A', rx, ',', ry, ',0,1,0,', dst.x, ',', dst.y
  62. );
  63. /*if(this.arrow) {
  64. }*/
  65. return link.path;
  66. }
  67. src = new ge.Point(link.source.x, link.source.y);
  68. dst = new ge.Point(link.target.x, link.target.y);
  69. var src2 = link.source.shape.intersect(link.source, link.target);
  70. var dst2 = link.target.shape.intersect(link.target, link.source);
  71. src = src2 || src;
  72. dst = dst2 || dst;
  73. var dst3 = dst;
  74. if(this.arrow) {
  75. dst3 = dst.clone().sub(src);
  76. var l = dst3.length();
  77. var l2 = this.arrowLength * this.arrowAngle.cos;
  78. dst3.mul(1 - l2 / l).add(src);
  79. }
  80. link.path = 'M'.concat(src.x, ',', src.y, 'L', dst3.x, ',', dst3.y);
  81. if(this.arrow) {
  82. link.path += this.arrowPath(src, dst);
  83. }
  84. if((link.reversed = src.x > dst.x)) {
  85. src2 = src;
  86. src = dst;
  87. dst = src2;
  88. }
  89. return 'M'.concat(src.x, ',', src.y, 'L', dst.x, ',', dst.y);
  90. };