@@ -62,29 +62,73 @@ public protocol Annotation {
6262 mutating func draw( resolver: CoordinateResolver , renderer: Renderer )
6363}
6464
65- struct Box : Annotation {
65+ public enum Direction {
66+ case north
67+ case east
68+ case south
69+ case west
70+ }
71+
72+ public protocol AnchorableAnnotation : Annotation {
73+ var direction : Direction { get set }
74+ var margin : Float { get set }
75+ mutating func resolve( renderer: Renderer , center: Point )
76+ }
77+
78+ struct Box : Annotation , AnchorableAnnotation {
6679 public var color = Color . black
6780 public var location = Point ( 0.0 , 0.0 )
6881 public var size = Size ( width: 0.0 , height: 0.0 )
82+ public var direction = Direction . north
83+ public var margin : Float = 5
84+ public mutating func resolve( renderer: Renderer , center: Point ) {
85+ switch ( direction) {
86+ case . north:
87+ location = Point ( center. x - size. width/ 2 , center. y + margin)
88+ case . east:
89+ location = Point ( center. x + margin, center. y - size. height/ 2 )
90+ case . south:
91+ location = Point ( center. x - size. width/ 2 , center. y - size. height - margin)
92+ case . west:
93+ location = Point ( center. x - size. width - margin, center. y - size. height/ 2 )
94+ }
95+ }
6996 public func draw( resolver: CoordinateResolver , renderer: Renderer ) {
7097 renderer. drawSolidRect ( Rect ( origin: location, size: size) ,
7198 fillColor: color,
7299 hatchPattern: . none)
73100 }
74- public init ( color: Color = . black, location: Point = Point ( 0.0 , 0.0 ) , size: Size = Size ( width: 0.0 , height: 0.0 ) ) {
101+ public init ( color: Color = . black, location: Point = Point ( 0.0 , 0.0 ) , size: Size = Size ( width: 0.0 , height: 0.0 ) , direction : Direction = . north , margin : Float = 5 ) {
75102 self . color = color
76103 self . location = location
77104 self . size = size
105+ self . direction = direction
106+ self . margin = margin
78107 }
79108}
80109
81- struct Text : Annotation {
110+ struct Text : Annotation , AnchorableAnnotation {
82111 public var text = " "
83112 public var color = Color . black
84113 public var size : Float = 15
85114 public var location = Point ( 0.0 , 0.0 )
86115 public var boundingBox : Box ?
87116 public var borderWidth : Float = 5
117+ public var direction = Direction . north
118+ public var margin : Float = 5
119+ public mutating func resolve( renderer: Renderer , center: Point ) {
120+ let width = renderer. getTextWidth ( text: text, textSize: size)
121+ switch ( direction) {
122+ case . north:
123+ location = Point ( center. x - width/ 2 , center. y + margin)
124+ case . east:
125+ location = Point ( center. x + margin, center. y - size/ 2 )
126+ case . south:
127+ location = Point ( center. x - width/ 2 , center. y - size - margin)
128+ case . west:
129+ location = Point ( center. x - width - margin, center. y - size/ 2 )
130+ }
131+ }
88132 public mutating func draw( resolver: CoordinateResolver , renderer: Renderer ) {
89133 if boundingBox != nil {
90134 var bboxSize = renderer. getTextLayoutSize ( text: text, textSize: size)
@@ -101,13 +145,15 @@ struct Text : Annotation {
101145 strokeWidth: 1.2 ,
102146 angle: 0 )
103147 }
104- public init ( text: String = " " , color: Color = . black, size: Float = 15 , location: Point = Point ( 0.0 , 0.0 ) , boundingBox: Box ? = nil , borderWidth: Float = 5 ) {
148+ public init ( text: String = " " , color: Color = . black, size: Float = 15 , location: Point = Point ( 0.0 , 0.0 ) , boundingBox: Box ? = nil , borderWidth: Float = 5 , direction : Direction = . north , margin : Float = 5 ) {
105149 self . text = text
106150 self . color = color
107151 self . size = size
108152 self . location = location
109153 self . boundingBox = boundingBox
110154 self . borderWidth = borderWidth
155+ self . direction = direction
156+ self . margin = margin
111157 }
112158}
113159
@@ -122,6 +168,7 @@ struct Arrow : Annotation {
122168 public var isFilled : Bool = false
123169 public var startAnnotation : Annotation ?
124170 public var endAnnotation : Annotation ?
171+ public var overrideAnchor : Bool = false
125172 public mutating func draw( resolver: CoordinateResolver , renderer: Renderer ) {
126173 // Draws arrow body.
127174 renderer. drawPlotLines ( points: [ start, end] ,
@@ -149,11 +196,34 @@ struct Arrow : Annotation {
149196 }
150197
151198 //Draws start and end annotations if specified.
152- startAnnotation? . draw ( resolver: resolver, renderer: renderer)
153- endAnnotation? . draw ( resolver: resolver, renderer: renderer)
154-
199+ if var startAnchor = startAnnotation as? AnchorableAnnotation {
200+ if !overrideAnchor {
201+ // Calculate anchor point
202+ var startAnchorPoint = start + Point( 0.0 , strokeWidth/ 2 )
203+ let startAnchorRotateAngle = - atan2( end. x - start. x, end. y - start. y)
204+ startAnchorPoint = rotatePoint ( point: startAnchorPoint, center: start, angleRadians: startAnchorRotateAngle + 0.5 * Float. pi)
205+ startAnchor. resolve ( renderer: renderer, center: startAnchorPoint)
206+ }
207+ startAnchor. draw ( resolver: resolver, renderer: renderer)
208+ }
209+ else {
210+ startAnnotation? . draw ( resolver: resolver, renderer: renderer)
211+ }
212+ if var endAnchor = endAnnotation as? AnchorableAnnotation {
213+ if !overrideAnchor {
214+ // Calculate anchor point
215+ var endAnchorPoint = end + Point( 0.0 , strokeWidth/ 2 )
216+ let endAnchorRotateAngle = - atan2( start. x - end. x, start. y - end. y)
217+ endAnchorPoint = rotatePoint ( point: endAnchorPoint, center: end, angleRadians: endAnchorRotateAngle + 0.5 * Float. pi)
218+ endAnchor. resolve ( renderer: renderer, center: endAnchorPoint)
219+ }
220+ endAnchor. draw ( resolver: resolver, renderer: renderer)
221+ }
222+ else {
223+ endAnnotation? . draw ( resolver: resolver, renderer: renderer)
224+ }
155225 }
156- public init ( color: Color = . black, start: Point = Point ( 0.0 , 0.0 ) , end: Point = Point ( 0.0 , 0.0 ) , strokeWidth: Float = 5 , headLength: Float = 10 , headAngle: Float = 20 , isDashed: Bool = false , isFilled: Bool = false , startAnnotation: Annotation ? = nil , endAnnotation: Annotation ? = nil ) {
226+ public init ( color: Color = . black, start: Point = Point ( 0.0 , 0.0 ) , end: Point = Point ( 0.0 , 0.0 ) , strokeWidth: Float = 5 , headLength: Float = 10 , headAngle: Float = 20 , isDashed: Bool = false , isFilled: Bool = false , startAnnotation: Annotation ? = nil , endAnnotation: Annotation ? = nil , overrideAnchor : Bool = false ) {
157227 self . color = color
158228 self . start = start
159229 self . end = end
@@ -164,5 +234,6 @@ struct Arrow : Annotation {
164234 self . isFilled = isFilled
165235 self . startAnnotation = startAnnotation
166236 self . endAnnotation = endAnnotation
237+ self . overrideAnchor = overrideAnchor
167238 }
168239}
0 commit comments