192 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
 | ||
| /*
 | ||
| * Licensed to the Apache Software Foundation (ASF) under one
 | ||
| * or more contributor license agreements.  See the NOTICE file
 | ||
| * distributed with this work for additional information
 | ||
| * regarding copyright ownership.  The ASF licenses this file
 | ||
| * to you under the Apache License, Version 2.0 (the
 | ||
| * "License"); you may not use this file except in compliance
 | ||
| * with the License.  You may obtain a copy of the License at
 | ||
| *
 | ||
| *   http://www.apache.org/licenses/LICENSE-2.0
 | ||
| *
 | ||
| * Unless required by applicable law or agreed to in writing,
 | ||
| * software distributed under the License is distributed on an
 | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | ||
| * KIND, either express or implied.  See the License for the
 | ||
| * specific language governing permissions and limitations
 | ||
| * under the License.
 | ||
| */
 | ||
| 
 | ||
| var curveTool = require("zrender/lib/core/curve");
 | ||
| 
 | ||
| var vec2 = require("zrender/lib/core/vector");
 | ||
| 
 | ||
| var _graphHelper = require("./graphHelper");
 | ||
| 
 | ||
| var getSymbolSize = _graphHelper.getSymbolSize;
 | ||
| 
 | ||
| /*
 | ||
| * Licensed to the Apache Software Foundation (ASF) under one
 | ||
| * or more contributor license agreements.  See the NOTICE file
 | ||
| * distributed with this work for additional information
 | ||
| * regarding copyright ownership.  The ASF licenses this file
 | ||
| * to you under the Apache License, Version 2.0 (the
 | ||
| * "License"); you may not use this file except in compliance
 | ||
| * with the License.  You may obtain a copy of the License at
 | ||
| *
 | ||
| *   http://www.apache.org/licenses/LICENSE-2.0
 | ||
| *
 | ||
| * Unless required by applicable law or agreed to in writing,
 | ||
| * software distributed under the License is distributed on an
 | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | ||
| * KIND, either express or implied.  See the License for the
 | ||
| * specific language governing permissions and limitations
 | ||
| * under the License.
 | ||
| */
 | ||
| var v1 = [];
 | ||
| var v2 = [];
 | ||
| var v3 = [];
 | ||
| var quadraticAt = curveTool.quadraticAt;
 | ||
| var v2DistSquare = vec2.distSquare;
 | ||
| var mathAbs = Math.abs;
 | ||
| 
 | ||
| function intersectCurveCircle(curvePoints, center, radius) {
 | ||
|   var p0 = curvePoints[0];
 | ||
|   var p1 = curvePoints[1];
 | ||
|   var p2 = curvePoints[2];
 | ||
|   var d = Infinity;
 | ||
|   var t;
 | ||
|   var radiusSquare = radius * radius;
 | ||
|   var interval = 0.1;
 | ||
| 
 | ||
|   for (var _t = 0.1; _t <= 0.9; _t += 0.1) {
 | ||
|     v1[0] = quadraticAt(p0[0], p1[0], p2[0], _t);
 | ||
|     v1[1] = quadraticAt(p0[1], p1[1], p2[1], _t);
 | ||
|     var diff = mathAbs(v2DistSquare(v1, center) - radiusSquare);
 | ||
| 
 | ||
|     if (diff < d) {
 | ||
|       d = diff;
 | ||
|       t = _t;
 | ||
|     }
 | ||
|   } // Assume the segment is monotone,Find root through Bisection method
 | ||
|   // At most 32 iteration
 | ||
| 
 | ||
| 
 | ||
|   for (var i = 0; i < 32; i++) {
 | ||
|     // var prev = t - interval;
 | ||
|     var next = t + interval; // v1[0] = quadraticAt(p0[0], p1[0], p2[0], prev);
 | ||
|     // v1[1] = quadraticAt(p0[1], p1[1], p2[1], prev);
 | ||
| 
 | ||
|     v2[0] = quadraticAt(p0[0], p1[0], p2[0], t);
 | ||
|     v2[1] = quadraticAt(p0[1], p1[1], p2[1], t);
 | ||
|     v3[0] = quadraticAt(p0[0], p1[0], p2[0], next);
 | ||
|     v3[1] = quadraticAt(p0[1], p1[1], p2[1], next);
 | ||
|     var diff = v2DistSquare(v2, center) - radiusSquare;
 | ||
| 
 | ||
|     if (mathAbs(diff) < 1e-2) {
 | ||
|       break;
 | ||
|     } // var prevDiff = v2DistSquare(v1, center) - radiusSquare;
 | ||
| 
 | ||
| 
 | ||
|     var nextDiff = v2DistSquare(v3, center) - radiusSquare;
 | ||
|     interval /= 2;
 | ||
| 
 | ||
|     if (diff < 0) {
 | ||
|       if (nextDiff >= 0) {
 | ||
|         t = t + interval;
 | ||
|       } else {
 | ||
|         t = t - interval;
 | ||
|       }
 | ||
|     } else {
 | ||
|       if (nextDiff >= 0) {
 | ||
|         t = t - interval;
 | ||
|       } else {
 | ||
|         t = t + interval;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   return t;
 | ||
| } // Adjust edge to avoid
 | ||
| 
 | ||
| 
 | ||
| function _default(graph, scale) {
 | ||
|   var tmp0 = [];
 | ||
|   var quadraticSubdivide = curveTool.quadraticSubdivide;
 | ||
|   var pts = [[], [], []];
 | ||
|   var pts2 = [[], []];
 | ||
|   var v = [];
 | ||
|   scale /= 2;
 | ||
|   graph.eachEdge(function (edge, idx) {
 | ||
|     var linePoints = edge.getLayout();
 | ||
|     var fromSymbol = edge.getVisual('fromSymbol');
 | ||
|     var toSymbol = edge.getVisual('toSymbol');
 | ||
| 
 | ||
|     if (!linePoints.__original) {
 | ||
|       linePoints.__original = [vec2.clone(linePoints[0]), vec2.clone(linePoints[1])];
 | ||
| 
 | ||
|       if (linePoints[2]) {
 | ||
|         linePoints.__original.push(vec2.clone(linePoints[2]));
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     var originalPoints = linePoints.__original; // Quadratic curve
 | ||
| 
 | ||
|     if (linePoints[2] != null) {
 | ||
|       vec2.copy(pts[0], originalPoints[0]);
 | ||
|       vec2.copy(pts[1], originalPoints[2]);
 | ||
|       vec2.copy(pts[2], originalPoints[1]);
 | ||
| 
 | ||
|       if (fromSymbol && fromSymbol !== 'none') {
 | ||
|         var symbolSize = getSymbolSize(edge.node1);
 | ||
|         var t = intersectCurveCircle(pts, originalPoints[0], symbolSize * scale); // Subdivide and get the second
 | ||
| 
 | ||
|         quadraticSubdivide(pts[0][0], pts[1][0], pts[2][0], t, tmp0);
 | ||
|         pts[0][0] = tmp0[3];
 | ||
|         pts[1][0] = tmp0[4];
 | ||
|         quadraticSubdivide(pts[0][1], pts[1][1], pts[2][1], t, tmp0);
 | ||
|         pts[0][1] = tmp0[3];
 | ||
|         pts[1][1] = tmp0[4];
 | ||
|       }
 | ||
| 
 | ||
|       if (toSymbol && toSymbol !== 'none') {
 | ||
|         var symbolSize = getSymbolSize(edge.node2);
 | ||
|         var t = intersectCurveCircle(pts, originalPoints[1], symbolSize * scale); // Subdivide and get the first
 | ||
| 
 | ||
|         quadraticSubdivide(pts[0][0], pts[1][0], pts[2][0], t, tmp0);
 | ||
|         pts[1][0] = tmp0[1];
 | ||
|         pts[2][0] = tmp0[2];
 | ||
|         quadraticSubdivide(pts[0][1], pts[1][1], pts[2][1], t, tmp0);
 | ||
|         pts[1][1] = tmp0[1];
 | ||
|         pts[2][1] = tmp0[2];
 | ||
|       } // Copy back to layout
 | ||
| 
 | ||
| 
 | ||
|       vec2.copy(linePoints[0], pts[0]);
 | ||
|       vec2.copy(linePoints[1], pts[2]);
 | ||
|       vec2.copy(linePoints[2], pts[1]);
 | ||
|     } // Line
 | ||
|     else {
 | ||
|         vec2.copy(pts2[0], originalPoints[0]);
 | ||
|         vec2.copy(pts2[1], originalPoints[1]);
 | ||
|         vec2.sub(v, pts2[1], pts2[0]);
 | ||
|         vec2.normalize(v, v);
 | ||
| 
 | ||
|         if (fromSymbol && fromSymbol !== 'none') {
 | ||
|           var symbolSize = getSymbolSize(edge.node1);
 | ||
|           vec2.scaleAndAdd(pts2[0], pts2[0], v, symbolSize * scale);
 | ||
|         }
 | ||
| 
 | ||
|         if (toSymbol && toSymbol !== 'none') {
 | ||
|           var symbolSize = getSymbolSize(edge.node2);
 | ||
|           vec2.scaleAndAdd(pts2[1], pts2[1], v, -symbolSize * scale);
 | ||
|         }
 | ||
| 
 | ||
|         vec2.copy(linePoints[0], pts2[0]);
 | ||
|         vec2.copy(linePoints[1], pts2[1]);
 | ||
|       }
 | ||
|   });
 | ||
| }
 | ||
| 
 | ||
| module.exports = _default; | 
