adjustEdge.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. var curveTool = require("zrender/lib/core/curve");
  2. var vec2 = require("zrender/lib/core/vector");
  3. var v1 = [];
  4. var v2 = [];
  5. var v3 = [];
  6. var quadraticAt = curveTool.quadraticAt;
  7. var v2DistSquare = vec2.distSquare;
  8. var mathAbs = Math.abs;
  9. function intersectCurveCircle(curvePoints, center, radius) {
  10. var p0 = curvePoints[0];
  11. var p1 = curvePoints[1];
  12. var p2 = curvePoints[2];
  13. var d = Infinity;
  14. var t;
  15. var radiusSquare = radius * radius;
  16. var interval = 0.1;
  17. for (var _t = 0.1; _t <= 0.9; _t += 0.1) {
  18. v1[0] = quadraticAt(p0[0], p1[0], p2[0], _t);
  19. v1[1] = quadraticAt(p0[1], p1[1], p2[1], _t);
  20. var diff = mathAbs(v2DistSquare(v1, center) - radiusSquare);
  21. if (diff < d) {
  22. d = diff;
  23. t = _t;
  24. }
  25. } // Assume the segment is monotone,Find root through Bisection method
  26. // At most 32 iteration
  27. for (var i = 0; i < 32; i++) {
  28. // var prev = t - interval;
  29. var next = t + interval; // v1[0] = quadraticAt(p0[0], p1[0], p2[0], prev);
  30. // v1[1] = quadraticAt(p0[1], p1[1], p2[1], prev);
  31. v2[0] = quadraticAt(p0[0], p1[0], p2[0], t);
  32. v2[1] = quadraticAt(p0[1], p1[1], p2[1], t);
  33. v3[0] = quadraticAt(p0[0], p1[0], p2[0], next);
  34. v3[1] = quadraticAt(p0[1], p1[1], p2[1], next);
  35. var diff = v2DistSquare(v2, center) - radiusSquare;
  36. if (mathAbs(diff) < 1e-2) {
  37. break;
  38. } // var prevDiff = v2DistSquare(v1, center) - radiusSquare;
  39. var nextDiff = v2DistSquare(v3, center) - radiusSquare;
  40. interval /= 2;
  41. if (diff < 0) {
  42. if (nextDiff >= 0) {
  43. t = t + interval;
  44. } else {
  45. t = t - interval;
  46. }
  47. } else {
  48. if (nextDiff >= 0) {
  49. t = t - interval;
  50. } else {
  51. t = t + interval;
  52. }
  53. }
  54. }
  55. return t;
  56. } // Adjust edge to avoid
  57. function _default(graph, scale) {
  58. var tmp0 = [];
  59. var quadraticSubdivide = curveTool.quadraticSubdivide;
  60. var pts = [[], [], []];
  61. var pts2 = [[], []];
  62. var v = [];
  63. scale /= 2;
  64. function getSymbolSize(node) {
  65. var symbolSize = node.getVisual('symbolSize');
  66. if (symbolSize instanceof Array) {
  67. symbolSize = (symbolSize[0] + symbolSize[1]) / 2;
  68. }
  69. return symbolSize;
  70. }
  71. graph.eachEdge(function (edge, idx) {
  72. var linePoints = edge.getLayout();
  73. var fromSymbol = edge.getVisual('fromSymbol');
  74. var toSymbol = edge.getVisual('toSymbol');
  75. if (!linePoints.__original) {
  76. linePoints.__original = [vec2.clone(linePoints[0]), vec2.clone(linePoints[1])];
  77. if (linePoints[2]) {
  78. linePoints.__original.push(vec2.clone(linePoints[2]));
  79. }
  80. }
  81. var originalPoints = linePoints.__original; // Quadratic curve
  82. if (linePoints[2] != null) {
  83. vec2.copy(pts[0], originalPoints[0]);
  84. vec2.copy(pts[1], originalPoints[2]);
  85. vec2.copy(pts[2], originalPoints[1]);
  86. if (fromSymbol && fromSymbol != 'none') {
  87. var symbolSize = getSymbolSize(edge.node1);
  88. var t = intersectCurveCircle(pts, originalPoints[0], symbolSize * scale); // Subdivide and get the second
  89. quadraticSubdivide(pts[0][0], pts[1][0], pts[2][0], t, tmp0);
  90. pts[0][0] = tmp0[3];
  91. pts[1][0] = tmp0[4];
  92. quadraticSubdivide(pts[0][1], pts[1][1], pts[2][1], t, tmp0);
  93. pts[0][1] = tmp0[3];
  94. pts[1][1] = tmp0[4];
  95. }
  96. if (toSymbol && toSymbol != 'none') {
  97. var symbolSize = getSymbolSize(edge.node2);
  98. var t = intersectCurveCircle(pts, originalPoints[1], symbolSize * scale); // Subdivide and get the first
  99. quadraticSubdivide(pts[0][0], pts[1][0], pts[2][0], t, tmp0);
  100. pts[1][0] = tmp0[1];
  101. pts[2][0] = tmp0[2];
  102. quadraticSubdivide(pts[0][1], pts[1][1], pts[2][1], t, tmp0);
  103. pts[1][1] = tmp0[1];
  104. pts[2][1] = tmp0[2];
  105. } // Copy back to layout
  106. vec2.copy(linePoints[0], pts[0]);
  107. vec2.copy(linePoints[1], pts[2]);
  108. vec2.copy(linePoints[2], pts[1]);
  109. } // Line
  110. else {
  111. vec2.copy(pts2[0], originalPoints[0]);
  112. vec2.copy(pts2[1], originalPoints[1]);
  113. vec2.sub(v, pts2[1], pts2[0]);
  114. vec2.normalize(v, v);
  115. if (fromSymbol && fromSymbol != 'none') {
  116. var symbolSize = getSymbolSize(edge.node1);
  117. vec2.scaleAndAdd(pts2[0], pts2[0], v, symbolSize * scale);
  118. }
  119. if (toSymbol && toSymbol != 'none') {
  120. var symbolSize = getSymbolSize(edge.node2);
  121. vec2.scaleAndAdd(pts2[1], pts2[1], v, -symbolSize * scale);
  122. }
  123. vec2.copy(linePoints[0], pts2[0]);
  124. vec2.copy(linePoints[1], pts2[1]);
  125. }
  126. });
  127. }
  128. module.exports = _default;