ErdRelationshipNodePainter.java |
1 /**************************************************************************** 2 * This demo file is part of yFiles for Java 2.14. 3 * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28, 4 * 72070 Tuebingen, Germany. All rights reserved. 5 * 6 * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution 7 * of demo files in source code or binary form, with or without 8 * modification, is not permitted. 9 * 10 * Owners of a valid software license for a yFiles for Java version that this 11 * demo is shipped with are allowed to use the demo source code as basis 12 * for their own yFiles for Java powered applications. Use of such programs is 13 * governed by the rights and conditions as set out in the yFiles for Java 14 * license agreement. 15 * 16 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 19 * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 ***************************************************************************/ 28 package demo.view.entityrelationship.painters; 29 30 import demo.view.flowchart.painters.FlowchartDecisionPainter; 31 import y.view.GenericNodeRealizer; 32 import y.view.LineType; 33 import y.view.NodeRealizer; 34 35 import java.awt.Shape; 36 import java.awt.geom.GeneralPath; 37 38 /** 39 * This is a painter to display a relationship node for entity relationship diagrams (ERD). 40 * 41 * A relationship is represented by a diamond shape. It is possible to display a weak 42 * relationship by drawing a double border. 43 */ 44 public class ErdRelationshipNodePainter extends FlowchartDecisionPainter { 45 private static final double EPSILON = 1.0e-12; 46 47 /** 48 * Calculates the interior shape for the specified node. 49 * @param context The node context 50 */ 51 protected Shape newDecoration( final NodeRealizer context ) { 52 if (!hasDoubleBorder(context)) { 53 return null; 54 } 55 56 final double width = context.getWidth(); 57 final double height = context.getHeight(); 58 if (Math.abs(width) < EPSILON || Math.abs(height) < EPSILON) { 59 return null; 60 } 61 62 final double x = context.getX(); 63 final double y = context.getY(); 64 65 final LineType lineType = context.getLineType(); 66 final float lw = lineType.getLineWidth(); 67 68 final double offset = 2 + lw; 69 70 final double w2 = width * 0.5; 71 final double h2 = height * 0.5; 72 73 // slope vector s = (w / 2, h / 2) 74 // normal vector n = (h / 2, - w / 2) 75 // length of normal vector 76 final double nl = Math.sqrt(w2 * w2 + h2 * h2); 77 78 // origin of line parallel to 0 + t*s with distance offset 79 final double ox = offset * h2 / nl; 80 final double oy = -offset * w2 / nl; 81 82 // intersection of line o + t*s with y == 0 83 final double ix = ox + (-oy / h2) * w2; 84 // intersection of line o + t*s with x == w / 2 85 final double iy = oy + (1 -ox / w2) * h2; 86 87 final double offsetX = ix; 88 final double offsetY = h2 - iy; 89 90 if (offsetX + lw < w2 && offsetY + lw < h2) { 91 final GeneralPath shapePath = new GeneralPath(); 92 shapePath.moveTo((float)(x + w2), (float)(y + offsetY)); 93 shapePath.lineTo((float)(x + width - offsetX), (float)(y + h2)); 94 shapePath.lineTo((float)(x + w2), (float)(y + height - offsetY)); 95 shapePath.lineTo((float)(x + offsetX) , (float)(y + h2)); 96 shapePath.closePath(); 97 return shapePath; 98 } else { 99 return null; 100 } 101 } 102 103 /** 104 * Tests if the style property {@link ErdRealizerFactory#DOUBLE_BORDER} is set for the context realizer. 105 * @param context The context node 106 * @return <code>true</code>, if style property border is set, <code>false</code> otherwise 107 */ 108 protected boolean hasDoubleBorder(NodeRealizer context) { 109 return Boolean.TRUE.equals(((GenericNodeRealizer) context).getStyleProperty(ErdRealizerFactory.DOUBLE_BORDER)); 110 } 111 } 112