Skip to content

Commit c421069

Browse files
committed
Rename "GraphLayout.Results" -> "GraphLayout.LayoutPlan"
1 parent 449d9be commit c421069

File tree

1 file changed

+85
-92
lines changed

1 file changed

+85
-92
lines changed

Sources/SwiftPlot/GraphLayout.swift

Lines changed: 85 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public struct GraphLayout {
3737
}
3838
var markerLabelAlignment = MarkerLabelAlignment.atMarker
3939

40-
struct Results : CoordinateResolver {
40+
struct LayoutPlan : CoordinateResolver {
4141
/// The size these results have been calculated for; the entire size of the plot.
4242
let totalSize: Size
4343

@@ -83,15 +83,8 @@ public struct GraphLayout {
8383

8484
extension GraphLayout {
8585

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-
9386
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) {
9588

9689
// 1. Calculate the plot size. To do that, we first have measure everything outside of the plot.
9790
let components = makeLayoutComponents()
@@ -101,21 +94,21 @@ extension GraphLayout {
10194
var plotSize = calcPlotSize(totalSize: size, componentSizes: sizes)
10295

10396
// 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)
10598
(drawingData as? AdjustsPlotSize).map { plotSize = adjustPlotSize(plotSize, info: $0) }
10699

107100
// 3. Now that we have the final sizes of everything, we can calculate their locations.
108101
let plotRect = layoutPlotRect(plotSize: plotSize, componentSizes: sizes)
109102
let roundedMarkers = markers.map { var m = $0; roundMarkers(&m); return m } ?? PlotMarkers()
110103

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)
119112
return (drawingData, results)
120113
}
121114

@@ -226,26 +219,26 @@ extension GraphLayout {
226219
// }
227220
}
228221

229-
private func calcMarkerTextLocations(renderer: Renderer, results: inout Results) {
222+
private func calcMarkerTextLocations(renderer: Renderer, plan: inout LayoutPlan) {
230223

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]
234227
var textLocation = Point(0, -2.0 * markerTextSize)
235228
switch markerLabelAlignment {
236229
case .atMarker:
237230
textLocation.x = markerLocation - (textWidth/2)
238231
case .betweenMarkers:
239232
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]
242235
} else {
243-
nextMarkerLocation = results.plotBorderRect.width
236+
nextMarkerLocation = plan.plotBorderRect.width
244237
}
245238
let midpoint = markerLocation + (nextMarkerLocation - markerLocation)/2
246239
textLocation.x = midpoint - (textWidth/2)
247240
}
248-
results.xMarkersTextLocation.append(textLocation)
241+
plan.xMarkersTextLocation.append(textLocation)
249242
}
250243

251244
/// Vertically aligns the label and returns the optimal Y coordinate to draw at.
@@ -259,33 +252,33 @@ extension GraphLayout {
259252
if index < markers.endIndex - 1 {
260253
nextMarkerLocation = markers[index + 1]
261254
} else {
262-
nextMarkerLocation = results.plotBorderRect.height
255+
nextMarkerLocation = plan.plotBorderRect.height
263256
}
264257
let midpoint = markerLocation + (nextMarkerLocation - markerLocation)/2
265258
return midpoint - (textSize.height/2)
266259
}
267260
}
268261

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],
271264
textSize: markerTextSize)
272265
textSize.width = min(textSize.width, yMarkerMaxWidth)
273266
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)
276269
}
277270

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],
280273
textSize: markerTextSize)
281274
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)
285278
}
286279
}
287280

288-
private func calcLegend(_ labels: [(String, LegendIcon)], renderer: Renderer, results: inout Results) {
281+
private func calcLegend(_ labels: [(String, LegendIcon)], renderer: Renderer, plan: inout LayoutPlan) {
289282
guard !labels.isEmpty else { return }
290283
let maxWidth = labels.lazy.map {
291284
renderer.getTextWidth(text: $0.0, textSize: self.plotLegend.textSize)
@@ -294,9 +287,9 @@ extension GraphLayout {
294287
let legendWidth = maxWidth + 3.5 * plotLegend.textSize
295288
let legendHeight = (Float(labels.count)*2.0 + 1.0) * plotLegend.textSize
296289

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(
300293
origin: legendTopLeft,
301294
size: Size(width: legendWidth, height: -legendHeight)
302295
).normalized
@@ -314,27 +307,27 @@ extension Renderer {
314307

315308
extension GraphLayout {
316309

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),
319312
fillColor: backgroundColor, hatchPattern: .none)
320313
if let plotBackgroundColor = plotBackgroundColor {
321-
renderer.drawSolidRect(results.plotBorderRect, fillColor: plotBackgroundColor, hatchPattern: .none)
314+
renderer.drawSolidRect(plan.plotBorderRect, fillColor: plotBackgroundColor, hatchPattern: .none)
322315
}
323316
if !drawsGridOverForeground {
324-
drawGrid(results: results, renderer: renderer)
317+
drawGrid(plan, renderer: renderer)
325318
}
326-
drawBorder(results: results, renderer: renderer)
327-
drawMarkers(results: results, renderer: renderer)
319+
drawBorder(plan, renderer: renderer)
320+
drawMarkers(plan, renderer: renderer)
328321
}
329322

330-
fileprivate func drawForeground(results: Results, renderer: Renderer) {
323+
fileprivate func drawForeground(_ plan: LayoutPlan, renderer: Renderer) {
331324
if drawsGridOverForeground {
332-
drawGrid(results: results, renderer: renderer)
325+
drawGrid(plan, renderer: renderer)
333326
}
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)
338331
}
339332

340333
private func drawLayoutComponents(_ components: EdgeComponents<[LayoutComponent]>, plotRect: Rect,
@@ -389,21 +382,21 @@ extension GraphLayout {
389382
}
390383
}
391384

392-
private func drawBorder(results: Results, renderer: Renderer) {
385+
private func drawBorder(_ plan: LayoutPlan, renderer: Renderer) {
393386
// The border should be drawn on the _outside_ of `plotBorderRect`.
394-
var rect = results.plotBorderRect
387+
var rect = plan.plotBorderRect
395388
rect.contract(by: -plotBorder.thickness/2)
396389
renderer.drawRect(rect,
397390
strokeWidth: plotBorder.thickness,
398391
strokeColor: plotBorder.color)
399392
}
400393

401-
private func drawGrid(results: Results, renderer: Renderer) {
394+
private func drawGrid(_ plan: LayoutPlan, renderer: Renderer) {
402395
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)
407400
guard rect.internalXCoordinates.contains(p1.x),
408401
rect.internalXCoordinates.contains(p2.x) else { continue }
409402
renderer.drawLine(startPoint: p1,
@@ -414,9 +407,9 @@ extension GraphLayout {
414407
}
415408

416409
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)
420413
guard rect.internalYCoordinates.contains(p1.y),
421414
rect.internalYCoordinates.contains(p2.y) else { continue }
422415
renderer.drawLine(startPoint: p1,
@@ -427,9 +420,9 @@ extension GraphLayout {
427420
}
428421
}
429422
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)
433426
guard rect.internalYCoordinates.contains(p1.y),
434427
rect.internalYCoordinates.contains(p2.y) else { continue }
435428
renderer.drawLine(startPoint: p1,
@@ -441,54 +434,54 @@ extension GraphLayout {
441434
}
442435
}
443436

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
446439
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
450443
renderer.drawLine(startPoint: p1,
451444
endPoint: p2,
452445
strokeWidth: markerThickness,
453446
strokeColor: plotBorder.color,
454447
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),
457450
textSize: markerTextSize,
458451
color: plotBorder.color,
459452
strokeWidth: 0.7,
460453
angle: 0)
461454
}
462455

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
466459
renderer.drawLine(startPoint: p1,
467460
endPoint: p2,
468461
strokeWidth: markerThickness,
469462
strokeColor: plotBorder.color,
470463
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),
473466
textSize: markerTextSize,
474467
color: plotBorder.color,
475468
strokeWidth: 0.7,
476469
angle: 0)
477470
}
478471

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
485478
renderer.drawLine(startPoint: p1,
486479
endPoint: p2,
487480
strokeWidth: markerThickness,
488481
strokeColor: plotBorder.color,
489482
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),
492485
textSize: markerTextSize,
493486
color: plotBorder.color,
494487
strokeWidth: 0.7,
@@ -497,9 +490,9 @@ extension GraphLayout {
497490
}
498491
}
499492

500-
private func drawLegend(_ entries: [(String, LegendIcon)], results: Results, renderer: Renderer) {
493+
private func drawLegend(_ entries: [(String, LegendIcon)], plan: LayoutPlan, renderer: Renderer) {
501494

502-
guard let legendRect = results.legendRect else { return }
495+
guard let legendRect = plan.legendRect else { return }
503496
renderer.drawSolidRectWithBorder(legendRect,
504497
strokeWidth: plotLegend.borderThickness,
505498
fillColor: plotLegend.backgroundColor,
@@ -624,16 +617,16 @@ extension HasGraphLayout {
624617
extension Plot where Self: HasGraphLayout {
625618

626619
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) {
628621
size -> (DrawingData, PlotMarkers?, [(String, LegendIcon)]?) in
629622
let tup = layoutData(size: size, renderer: renderer)
630623
return (tup.0, tup.1, self.legendLabels)
631624
}
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)
635628
}
636-
layout.drawForeground(results: results, renderer: renderer)
629+
layout.drawForeground(plan, renderer: renderer)
637630
}
638631

639632
public mutating func addAnnotation(annotation: Annotation) {

0 commit comments

Comments
 (0)