@@ -62,29 +62,73 @@ public protocol Annotation {
62
62
mutating func draw( resolver: CoordinateResolver , renderer: Renderer )
63
63
}
64
64
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 {
66
79
public var color = Color . black
67
80
public var location = Point ( 0.0 , 0.0 )
68
81
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
+ }
69
96
public func draw( resolver: CoordinateResolver , renderer: Renderer ) {
70
97
renderer. drawSolidRect ( Rect ( origin: location, size: size) ,
71
98
fillColor: color,
72
99
hatchPattern: . none)
73
100
}
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 ) {
75
102
self . color = color
76
103
self . location = location
77
104
self . size = size
105
+ self . direction = direction
106
+ self . margin = margin
78
107
}
79
108
}
80
109
81
- struct Text : Annotation {
110
+ struct Text : Annotation , AnchorableAnnotation {
82
111
public var text = " "
83
112
public var color = Color . black
84
113
public var size : Float = 15
85
114
public var location = Point ( 0.0 , 0.0 )
86
115
public var boundingBox : Box ?
87
116
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
+ }
88
132
public mutating func draw( resolver: CoordinateResolver , renderer: Renderer ) {
89
133
if boundingBox != nil {
90
134
var bboxSize = renderer. getTextLayoutSize ( text: text, textSize: size)
@@ -101,13 +145,15 @@ struct Text : Annotation {
101
145
strokeWidth: 1.2 ,
102
146
angle: 0 )
103
147
}
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 ) {
105
149
self . text = text
106
150
self . color = color
107
151
self . size = size
108
152
self . location = location
109
153
self . boundingBox = boundingBox
110
154
self . borderWidth = borderWidth
155
+ self . direction = direction
156
+ self . margin = margin
111
157
}
112
158
}
113
159
@@ -122,6 +168,7 @@ struct Arrow : Annotation {
122
168
public var isFilled : Bool = false
123
169
public var startAnnotation : Annotation ?
124
170
public var endAnnotation : Annotation ?
171
+ public var overrideAnchor : Bool = false
125
172
public mutating func draw( resolver: CoordinateResolver , renderer: Renderer ) {
126
173
// Draws arrow body.
127
174
renderer. drawPlotLines ( points: [ start, end] ,
@@ -149,11 +196,34 @@ struct Arrow : Annotation {
149
196
}
150
197
151
198
//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
+ }
155
225
}
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 ) {
157
227
self . color = color
158
228
self . start = start
159
229
self . end = end
@@ -164,5 +234,6 @@ struct Arrow : Annotation {
164
234
self . isFilled = isFilled
165
235
self . startAnnotation = startAnnotation
166
236
self . endAnnotation = endAnnotation
237
+ self . overrideAnchor = overrideAnchor
167
238
}
168
239
}
0 commit comments