@@ -37,7 +37,7 @@ public struct GraphLayout {
37
37
}
38
38
var markerLabelAlignment = MarkerLabelAlignment . atMarker
39
39
40
- struct Results : CoordinateResolver {
40
+ struct LayoutPlan : CoordinateResolver {
41
41
/// The size these results have been calculated for; the entire size of the plot.
42
42
let totalSize : Size
43
43
@@ -83,15 +83,8 @@ public struct GraphLayout {
83
83
84
84
extension GraphLayout {
85
85
86
- // TODO: refactor "calculateMarkers":
87
- // - Should be called "layoutContent" or something like that.
88
- // - PlotMarkers return value should be an array of `LayoutComponent`s.
89
- // - Legend info should be handled by an annotation.
90
- // - Possibly wrap T inside `Results` (as a generic parameter).
91
- // - Rename `Results` to `LayoutPlan` or something like that.
92
-
93
86
func layout< T> ( size: Size , renderer: Renderer ,
94
- calculateMarkers : ( Size ) -> ( T , PlotMarkers ? , [ ( String , LegendIcon ) ] ? ) ) -> ( T , Results ) {
87
+ layoutContent : ( Size ) -> ( T , PlotMarkers ? , [ ( String , LegendIcon ) ] ? ) ) -> ( T , LayoutPlan ) {
95
88
96
89
// 1. Calculate the plot size. To do that, we first have measure everything outside of the plot.
97
90
let components = makeLayoutComponents ( )
@@ -101,21 +94,21 @@ extension GraphLayout {
101
94
var plotSize = calcPlotSize ( totalSize: size, componentSizes: sizes)
102
95
103
96
// 2. Call back to the plot to lay out its data. It may ask to adjust the plot size.
104
- let ( drawingData, markers, legendInfo) = calculateMarkers ( plotSize)
97
+ let ( drawingData, markers, legendInfo) = layoutContent ( plotSize)
105
98
( drawingData as? AdjustsPlotSize ) . map { plotSize = adjustPlotSize ( plotSize, info: $0) }
106
99
107
100
// 3. Now that we have the final sizes of everything, we can calculate their locations.
108
101
let plotRect = layoutPlotRect ( plotSize: plotSize, componentSizes: sizes)
109
102
let roundedMarkers = markers. map { var m = $0; roundMarkers ( & m) ; return m } ?? PlotMarkers ( )
110
103
111
- var results = Results ( totalSize: size,
112
- plotBorderRect: plotRect,
113
- components: components,
114
- sizes: sizes,
115
- plotMarkers: roundedMarkers,
116
- legendLabels: legendInfo ?? [ ] )
117
- calcMarkerTextLocations ( renderer: renderer, results : & results)
118
- calcLegend ( results. legendLabels, renderer: renderer, results : & results)
104
+ var results = LayoutPlan ( totalSize: size,
105
+ plotBorderRect: plotRect,
106
+ components: components,
107
+ sizes: sizes,
108
+ plotMarkers: roundedMarkers,
109
+ legendLabels: legendInfo ?? [ ] )
110
+ calcMarkerTextLocations ( renderer: renderer, plan : & results)
111
+ calcLegend ( results. legendLabels, renderer: renderer, plan : & results)
119
112
return ( drawingData, results)
120
113
}
121
114
@@ -226,26 +219,26 @@ extension GraphLayout {
226
219
// }
227
220
}
228
221
229
- private func calcMarkerTextLocations( renderer: Renderer , results : inout Results ) {
222
+ private func calcMarkerTextLocations( renderer: Renderer , plan : inout LayoutPlan ) {
230
223
231
- for i in 0 ..< results . plotMarkers. xMarkers. count {
232
- let textWidth = renderer. getTextWidth ( text: results . plotMarkers. xMarkersText [ i] , textSize: markerTextSize)
233
- let markerLocation = results . plotMarkers. xMarkers [ i]
224
+ for i in 0 ..< plan . plotMarkers. xMarkers. count {
225
+ let textWidth = renderer. getTextWidth ( text: plan . plotMarkers. xMarkersText [ i] , textSize: markerTextSize)
226
+ let markerLocation = plan . plotMarkers. xMarkers [ i]
234
227
var textLocation = Point ( 0 , - 2.0 * markerTextSize)
235
228
switch markerLabelAlignment {
236
229
case . atMarker:
237
230
textLocation. x = markerLocation - ( textWidth/ 2 )
238
231
case . betweenMarkers:
239
232
let nextMarkerLocation : Float
240
- if i < results . plotMarkers. xMarkers. endIndex - 1 {
241
- nextMarkerLocation = results . plotMarkers. xMarkers [ i + 1 ]
233
+ if i < plan . plotMarkers. xMarkers. endIndex - 1 {
234
+ nextMarkerLocation = plan . plotMarkers. xMarkers [ i + 1 ]
242
235
} else {
243
- nextMarkerLocation = results . plotBorderRect. width
236
+ nextMarkerLocation = plan . plotBorderRect. width
244
237
}
245
238
let midpoint = markerLocation + ( nextMarkerLocation - markerLocation) / 2
246
239
textLocation. x = midpoint - ( textWidth/ 2 )
247
240
}
248
- results . xMarkersTextLocation. append ( textLocation)
241
+ plan . xMarkersTextLocation. append ( textLocation)
249
242
}
250
243
251
244
/// Vertically aligns the label and returns the optimal Y coordinate to draw at.
@@ -259,33 +252,33 @@ extension GraphLayout {
259
252
if index < markers. endIndex - 1 {
260
253
nextMarkerLocation = markers [ index + 1 ]
261
254
} else {
262
- nextMarkerLocation = results . plotBorderRect. height
255
+ nextMarkerLocation = plan . plotBorderRect. height
263
256
}
264
257
let midpoint = markerLocation + ( nextMarkerLocation - markerLocation) / 2
265
258
return midpoint - ( textSize. height/ 2 )
266
259
}
267
260
}
268
261
269
- for i in 0 ..< results . plotMarkers. yMarkers. count {
270
- var textSize = renderer. getTextLayoutSize ( text: results . plotMarkers. yMarkersText [ i] ,
262
+ for i in 0 ..< plan . plotMarkers. yMarkers. count {
263
+ var textSize = renderer. getTextLayoutSize ( text: plan . plotMarkers. yMarkersText [ i] ,
271
264
textSize: markerTextSize)
272
265
textSize. width = min ( textSize. width, yMarkerMaxWidth)
273
266
var textLocation = Point ( - textSize. width - 8 , 0 )
274
- textLocation. y = alignYLabel ( markers: results . plotMarkers. yMarkers, index: i, textSize: textSize)
275
- results . yMarkersTextLocation. append ( textLocation)
267
+ textLocation. y = alignYLabel ( markers: plan . plotMarkers. yMarkers, index: i, textSize: textSize)
268
+ plan . yMarkersTextLocation. append ( textLocation)
276
269
}
277
270
278
- for i in 0 ..< results . plotMarkers. y2Markers. count {
279
- var textSize = renderer. getTextLayoutSize ( text: results . plotMarkers. y2MarkersText [ i] ,
271
+ for i in 0 ..< plan . plotMarkers. y2Markers. count {
272
+ var textSize = renderer. getTextLayoutSize ( text: plan . plotMarkers. y2MarkersText [ i] ,
280
273
textSize: markerTextSize)
281
274
textSize. width = min ( textSize. width, yMarkerMaxWidth)
282
- var textLocation = Point ( results . plotBorderRect. width + 8 , 0 )
283
- textLocation. y = alignYLabel ( markers: results . plotMarkers. y2Markers, index: i, textSize: textSize)
284
- results . y2MarkersTextLocation. append ( textLocation)
275
+ var textLocation = Point ( plan . plotBorderRect. width + 8 , 0 )
276
+ textLocation. y = alignYLabel ( markers: plan . plotMarkers. y2Markers, index: i, textSize: textSize)
277
+ plan . y2MarkersTextLocation. append ( textLocation)
285
278
}
286
279
}
287
280
288
- private func calcLegend( _ labels: [ ( String , LegendIcon ) ] , renderer: Renderer , results : inout Results ) {
281
+ private func calcLegend( _ labels: [ ( String , LegendIcon ) ] , renderer: Renderer , plan : inout LayoutPlan ) {
289
282
guard !labels. isEmpty else { return }
290
283
let maxWidth = labels. lazy. map {
291
284
renderer. getTextWidth ( text: $0. 0 , textSize: self . plotLegend. textSize)
@@ -294,9 +287,9 @@ extension GraphLayout {
294
287
let legendWidth = maxWidth + 3.5 * plotLegend. textSize
295
288
let legendHeight = ( Float ( labels. count) * 2.0 + 1.0 ) * plotLegend. textSize
296
289
297
- let legendTopLeft = Point ( results . plotBorderRect. minX + Float( 20 ) ,
298
- results . plotBorderRect. maxY - Float( 20 ) )
299
- results . legendRect = Rect (
290
+ let legendTopLeft = Point ( plan . plotBorderRect. minX + Float( 20 ) ,
291
+ plan . plotBorderRect. maxY - Float( 20 ) )
292
+ plan . legendRect = Rect (
300
293
origin: legendTopLeft,
301
294
size: Size ( width: legendWidth, height: - legendHeight)
302
295
) . normalized
@@ -314,27 +307,27 @@ extension Renderer {
314
307
315
308
extension GraphLayout {
316
309
317
- fileprivate func drawBackground( results : Results , renderer: Renderer ) {
318
- renderer. drawSolidRect ( Rect ( origin: . zero, size: results . totalSize) ,
310
+ fileprivate func drawBackground( _ plan : LayoutPlan , renderer: Renderer ) {
311
+ renderer. drawSolidRect ( Rect ( origin: . zero, size: plan . totalSize) ,
319
312
fillColor: backgroundColor, hatchPattern: . none)
320
313
if let plotBackgroundColor = plotBackgroundColor {
321
- renderer. drawSolidRect ( results . plotBorderRect, fillColor: plotBackgroundColor, hatchPattern: . none)
314
+ renderer. drawSolidRect ( plan . plotBorderRect, fillColor: plotBackgroundColor, hatchPattern: . none)
322
315
}
323
316
if !drawsGridOverForeground {
324
- drawGrid ( results : results , renderer: renderer)
317
+ drawGrid ( plan , renderer: renderer)
325
318
}
326
- drawBorder ( results : results , renderer: renderer)
327
- drawMarkers ( results : results , renderer: renderer)
319
+ drawBorder ( plan , renderer: renderer)
320
+ drawMarkers ( plan , renderer: renderer)
328
321
}
329
322
330
- fileprivate func drawForeground( results : Results , renderer: Renderer ) {
323
+ fileprivate func drawForeground( _ plan : LayoutPlan , renderer: Renderer ) {
331
324
if drawsGridOverForeground {
332
- drawGrid ( results : results , renderer: renderer)
325
+ drawGrid ( plan , renderer: renderer)
333
326
}
334
- drawLayoutComponents ( results . components, plotRect: results . plotBorderRect,
335
- measuredSizes: results . sizes, renderer: renderer)
336
- drawLegend ( results . legendLabels, results : results , renderer: renderer)
337
- drawAnnotations ( resolver: results , renderer: renderer)
327
+ drawLayoutComponents ( plan . components, plotRect: plan . plotBorderRect,
328
+ measuredSizes: plan . sizes, renderer: renderer)
329
+ drawLegend ( plan . legendLabels, plan : plan , renderer: renderer)
330
+ drawAnnotations ( resolver: plan , renderer: renderer)
338
331
}
339
332
340
333
private func drawLayoutComponents( _ components: EdgeComponents < [ LayoutComponent ] > , plotRect: Rect ,
@@ -389,21 +382,21 @@ extension GraphLayout {
389
382
}
390
383
}
391
384
392
- private func drawBorder( results : Results , renderer: Renderer ) {
385
+ private func drawBorder( _ plan : LayoutPlan , renderer: Renderer ) {
393
386
// The border should be drawn on the _outside_ of `plotBorderRect`.
394
- var rect = results . plotBorderRect
387
+ var rect = plan . plotBorderRect
395
388
rect. contract ( by: - plotBorder. thickness/ 2 )
396
389
renderer. drawRect ( rect,
397
390
strokeWidth: plotBorder. thickness,
398
391
strokeColor: plotBorder. color)
399
392
}
400
393
401
- private func drawGrid( results : Results , renderer: Renderer ) {
394
+ private func drawGrid( _ plan : LayoutPlan , renderer: Renderer ) {
402
395
guard enablePrimaryAxisGrid || enablePrimaryAxisGrid else { return }
403
- let rect = results . plotBorderRect
404
- for index in 0 ..< results . plotMarkers. xMarkers. count {
405
- let p1 = Point ( results . plotMarkers. xMarkers [ index] + rect. minX, rect. minY)
406
- let p2 = Point ( results . plotMarkers. xMarkers [ index] + rect. minX, rect. maxY)
396
+ let rect = plan . plotBorderRect
397
+ for index in 0 ..< plan . plotMarkers. xMarkers. count {
398
+ let p1 = Point ( plan . plotMarkers. xMarkers [ index] + rect. minX, rect. minY)
399
+ let p2 = Point ( plan . plotMarkers. xMarkers [ index] + rect. minX, rect. maxY)
407
400
guard rect. internalXCoordinates. contains ( p1. x) ,
408
401
rect. internalXCoordinates. contains ( p2. x) else { continue }
409
402
renderer. drawLine ( startPoint: p1,
@@ -414,9 +407,9 @@ extension GraphLayout {
414
407
}
415
408
416
409
if ( enablePrimaryAxisGrid) {
417
- for index in 0 ..< results . plotMarkers. yMarkers. count {
418
- let p1 = Point ( rect. minX, results . plotMarkers. yMarkers [ index] + rect. minY)
419
- let p2 = Point ( rect. maxX, results . plotMarkers. yMarkers [ index] + rect. minY)
410
+ for index in 0 ..< plan . plotMarkers. yMarkers. count {
411
+ let p1 = Point ( rect. minX, plan . plotMarkers. yMarkers [ index] + rect. minY)
412
+ let p2 = Point ( rect. maxX, plan . plotMarkers. yMarkers [ index] + rect. minY)
420
413
guard rect. internalYCoordinates. contains ( p1. y) ,
421
414
rect. internalYCoordinates. contains ( p2. y) else { continue }
422
415
renderer. drawLine ( startPoint: p1,
@@ -427,9 +420,9 @@ extension GraphLayout {
427
420
}
428
421
}
429
422
if ( enableSecondaryAxisGrid) {
430
- for index in 0 ..< results . plotMarkers. y2Markers. count {
431
- let p1 = Point ( rect. minX, results . plotMarkers. y2Markers [ index] + rect. minY)
432
- let p2 = Point ( rect. maxX, results . plotMarkers. y2Markers [ index] + rect. minY)
423
+ for index in 0 ..< plan . plotMarkers. y2Markers. count {
424
+ let p1 = Point ( rect. minX, plan . plotMarkers. y2Markers [ index] + rect. minY)
425
+ let p2 = Point ( rect. maxX, plan . plotMarkers. y2Markers [ index] + rect. minY)
433
426
guard rect. internalYCoordinates. contains ( p1. y) ,
434
427
rect. internalYCoordinates. contains ( p2. y) else { continue }
435
428
renderer. drawLine ( startPoint: p1,
@@ -441,54 +434,54 @@ extension GraphLayout {
441
434
}
442
435
}
443
436
444
- private func drawMarkers( results : Results , renderer: Renderer ) {
445
- let rect = results . plotBorderRect
437
+ private func drawMarkers( _ plan : LayoutPlan , renderer: Renderer ) {
438
+ let rect = plan . plotBorderRect
446
439
let border = plotBorder. thickness
447
- for index in 0 ..< results . plotMarkers. xMarkers. count {
448
- let p1 = Point ( results . plotMarkers. xMarkers [ index] , - border - 6 ) + rect. origin
449
- let p2 = Point ( results . plotMarkers. xMarkers [ index] , - border) + rect. origin
440
+ for index in 0 ..< plan . plotMarkers. xMarkers. count {
441
+ let p1 = Point ( plan . plotMarkers. xMarkers [ index] , - border - 6 ) + rect. origin
442
+ let p2 = Point ( plan . plotMarkers. xMarkers [ index] , - border) + rect. origin
450
443
renderer. drawLine ( startPoint: p1,
451
444
endPoint: p2,
452
445
strokeWidth: markerThickness,
453
446
strokeColor: plotBorder. color,
454
447
isDashed: false )
455
- renderer. drawText ( text: results . plotMarkers. xMarkersText [ index] ,
456
- location: results . xMarkersTextLocation [ index] + rect. origin + Pair( 0 , - border) ,
448
+ renderer. drawText ( text: plan . plotMarkers. xMarkersText [ index] ,
449
+ location: plan . xMarkersTextLocation [ index] + rect. origin + Pair( 0 , - border) ,
457
450
textSize: markerTextSize,
458
451
color: plotBorder. color,
459
452
strokeWidth: 0.7 ,
460
453
angle: 0 )
461
454
}
462
455
463
- for index in 0 ..< results . plotMarkers. yMarkers. count {
464
- let p1 = Point ( - border - 6 , results . plotMarkers. yMarkers [ index] ) + rect. origin
465
- let p2 = Point ( - border, results . plotMarkers. yMarkers [ index] ) + rect. origin
456
+ for index in 0 ..< plan . plotMarkers. yMarkers. count {
457
+ let p1 = Point ( - border - 6 , plan . plotMarkers. yMarkers [ index] ) + rect. origin
458
+ let p2 = Point ( - border, plan . plotMarkers. yMarkers [ index] ) + rect. origin
466
459
renderer. drawLine ( startPoint: p1,
467
460
endPoint: p2,
468
461
strokeWidth: markerThickness,
469
462
strokeColor: plotBorder. color,
470
463
isDashed: false )
471
- renderer. drawText ( text: results . plotMarkers. yMarkersText [ index] ,
472
- location: results . yMarkersTextLocation [ index] + rect. origin + Pair( - border, 0 ) ,
464
+ renderer. drawText ( text: plan . plotMarkers. yMarkersText [ index] ,
465
+ location: plan . yMarkersTextLocation [ index] + rect. origin + Pair( - border, 0 ) ,
473
466
textSize: markerTextSize,
474
467
color: plotBorder. color,
475
468
strokeWidth: 0.7 ,
476
469
angle: 0 )
477
470
}
478
471
479
- if !results . plotMarkers. y2Markers. isEmpty {
480
- for index in 0 ..< results . plotMarkers. y2Markers. count {
481
- let p1 = Point ( results . plotBorderRect. width + border,
482
- ( results . plotMarkers. y2Markers [ index] ) ) + rect. origin
483
- let p2 = Point ( results . plotBorderRect. width + border + 6 ,
484
- ( results . plotMarkers. y2Markers [ index] ) ) + rect. origin
472
+ if !plan . plotMarkers. y2Markers. isEmpty {
473
+ for index in 0 ..< plan . plotMarkers. y2Markers. count {
474
+ let p1 = Point ( plan . plotBorderRect. width + border,
475
+ ( plan . plotMarkers. y2Markers [ index] ) ) + rect. origin
476
+ let p2 = Point ( plan . plotBorderRect. width + border + 6 ,
477
+ ( plan . plotMarkers. y2Markers [ index] ) ) + rect. origin
485
478
renderer. drawLine ( startPoint: p1,
486
479
endPoint: p2,
487
480
strokeWidth: markerThickness,
488
481
strokeColor: plotBorder. color,
489
482
isDashed: false )
490
- renderer. drawText ( text: results . plotMarkers. y2MarkersText [ index] ,
491
- location: results . y2MarkersTextLocation [ index] + rect. origin + Pair( border, 0 ) ,
483
+ renderer. drawText ( text: plan . plotMarkers. y2MarkersText [ index] ,
484
+ location: plan . y2MarkersTextLocation [ index] + rect. origin + Pair( border, 0 ) ,
492
485
textSize: markerTextSize,
493
486
color: plotBorder. color,
494
487
strokeWidth: 0.7 ,
@@ -497,9 +490,9 @@ extension GraphLayout {
497
490
}
498
491
}
499
492
500
- private func drawLegend( _ entries: [ ( String , LegendIcon ) ] , results : Results , renderer: Renderer ) {
493
+ private func drawLegend( _ entries: [ ( String , LegendIcon ) ] , plan : LayoutPlan , renderer: Renderer ) {
501
494
502
- guard let legendRect = results . legendRect else { return }
495
+ guard let legendRect = plan . legendRect else { return }
503
496
renderer. drawSolidRectWithBorder ( legendRect,
504
497
strokeWidth: plotLegend. borderThickness,
505
498
fillColor: plotLegend. backgroundColor,
@@ -624,16 +617,16 @@ extension HasGraphLayout {
624
617
extension Plot where Self: HasGraphLayout {
625
618
626
619
public func drawGraph( size: Size , renderer: Renderer ) {
627
- let ( drawingData, results ) = layout. layout ( size: size, renderer: renderer) {
620
+ let ( drawingData, plan ) = layout. layout ( size: size, renderer: renderer) {
628
621
size -> ( DrawingData , PlotMarkers ? , [ ( String , LegendIcon ) ] ? ) in
629
622
let tup = layoutData ( size: size, renderer: renderer)
630
623
return ( tup. 0 , tup. 1 , self . legendLabels)
631
624
}
632
- layout. drawBackground ( results : results , renderer: renderer)
633
- renderer. withAdditionalOffset ( results . plotBorderRect. origin) { renderer in
634
- drawData ( drawingData, size: results . plotBorderRect. size, renderer: renderer)
625
+ layout. drawBackground ( plan , renderer: renderer)
626
+ renderer. withAdditionalOffset ( plan . plotBorderRect. origin) { renderer in
627
+ drawData ( drawingData, size: plan . plotBorderRect. size, renderer: renderer)
635
628
}
636
- layout. drawForeground ( results : results , renderer: renderer)
629
+ layout. drawForeground ( plan , renderer: renderer)
637
630
}
638
631
639
632
public mutating func addAnnotation( annotation: Annotation ) {
0 commit comments