1 package com.jgraph.io.svg; 2 3 import java.awt.Point; 4 import java.awt.geom.Point2D; 5 import java.awt.geom.Rectangle2D; 6 7 import org.jgraph.graph.CellView; 8 import org.jgraph.graph.VertexRenderer; 9 import org.jgraph.graph.VertexView; 10 11 public class SVGVertexRenderer extends VertexRenderer { 12 13 /** 14 * Holds the shape of the current view. 15 */ 16 protected int shape = 0; 17 getPerimeterPoint(VertexView view, Point2D source, Point2D p)18 public Point2D getPerimeterPoint(VertexView view, Point2D source, 19 Point2D p) { 20 int shape = SVGGraphConstants 21 .getShape(view.getAllAttributes()); 22 if (shape == SVGGraphConstants.SHAPE_ELLIPSE) { 23 return getEllipsePerimeterPoint(view, source, p); 24 } 25 return super.getPerimeterPoint(view, source, p); 26 } 27 installAttributes(CellView view)28 public void installAttributes(CellView view) { 29 super.installAttributes(view); 30 // Map map = view.getAllAttributes(); 31 shape = SVGGraphConstants.getShape(view.getAllAttributes()); 32 } 33 34 /** 35 * Utility method to return the perimeter point for a circle. 36 * 37 * @param view 38 * The view that defines the bounds of the circle. 39 * @param source 40 * The start point of theline to intersect with the circle. 41 * @param p 42 * The end point of the line to intersect with the circle. 43 * @return The interaction of the circle and the line between source and 44 * p. 45 */ getEllipsePerimeterPoint(VertexView view, Point2D source, Point2D p)46 public Point2D getEllipsePerimeterPoint(VertexView view, 47 Point2D source, Point2D p) { 48 Rectangle2D r = view.getBounds(); 49 50 double x = r.getX(); 51 double y = r.getY(); 52 double a = (r.getWidth() + 1) / 2; 53 double b = (r.getHeight() + 1) / 2; 54 55 // x0,y0 - center of ellipse 56 double x0 = x + a; 57 double y0 = y + b; 58 59 // x1, y1 - point 60 double x1 = p.getX(); 61 double y1 = p.getY(); 62 63 // Calculates straight line equation through point and ellipse 64 // center 65 // y = d * x + h 66 double dx = x1 - x0; 67 double dy = y1 - y0; 68 69 if (dx == 0) 70 return new Point((int) x0, (int) (y0 + b * dy / Math.abs(dy))); 71 72 double d = dy / dx; 73 double h = y0 - d * x0; 74 75 // Calculates intersection 76 double e = a * a * d * d + b * b; 77 double f = -2 * x0 * e; 78 double g = a * a * d * d * x0 * x0 + b * b * x0 * x0 - a * a * b 79 * b; 80 81 double det = Math.sqrt(f * f - 4 * e * g); 82 83 // Two solutions (perimeter points) 84 double xout1 = (-f + det) / (2 * e); 85 double xout2 = (-f - det) / (2 * e); 86 double yout1 = d * xout1 + h; 87 double yout2 = d * xout2 + h; 88 89 double dist1 = Math.sqrt(Math.pow((xout1 - x1), 2) 90 + Math.pow((yout1 - y1), 2)); 91 double dist2 = Math.sqrt(Math.pow((xout2 - x1), 2) 92 + Math.pow((yout2 - y1), 2)); 93 94 // Correct solution 95 double xout, yout; 96 97 if (dist1 < dist2) { 98 xout = xout1; 99 yout = yout1; 100 } else { 101 xout = xout2; 102 yout = yout2; 103 } 104 105 return new Point2D.Double(xout, yout); 106 } 107 108 }