Skip to content

Commit fd134a1

Browse files
committed
expanding nice to bolster upper and lower values using current Calendar, updated tests to match
1 parent 20653c1 commit fd134a1

File tree

4 files changed

+67
-25
lines changed

4 files changed

+67
-25
lines changed

Sources/SwiftVizScale/DateScale.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,8 @@ public struct DateScale<OutputType: BinaryFloatingPoint>: ReversibleScale, Custo
116116
}
117117
precondition(min < max)
118118
if nice {
119-
let magnitude = DateMagnitude.magnitudeOfDateRange(min, max)
120-
if let bottom = min.round(magnitude: magnitude, calendar: Calendar.current) {
121-
return domain(lower: bottom, higher: max)
122-
}
119+
let (newMin, newMax) = Date.niceExpandDomain(min: min, max: max, calendar: Calendar.current)
120+
return domain(lower: newMin, higher: newMax)
123121
}
124122
return domain(lower: min, higher: max)
125123
}

Sources/SwiftVizScale/NiceValue.swift

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -432,53 +432,53 @@ public extension Date {
432432
}
433433
return niceFraction
434434
case .minutes:
435-
let stepFractionInMinutes = step / DateMagnitude.minutesThreshold.lowerBound
435+
let stepFractionInMinutes = step / DateMagnitude.minutes.seconds
436436
if stepFractionInMinutes <= 1 {
437-
niceFraction = 1 * DateMagnitude.minutesThreshold.lowerBound
437+
niceFraction = 1 * DateMagnitude.minutes.seconds
438438
} else if stepFractionInMinutes <= 2 {
439-
niceFraction = 2 * DateMagnitude.minutesThreshold.lowerBound
439+
niceFraction = 2 * DateMagnitude.minutes.seconds
440440
} else if stepFractionInMinutes <= 5 {
441-
niceFraction = 5 * DateMagnitude.minutesThreshold.lowerBound
441+
niceFraction = 5 * DateMagnitude.minutes.seconds
442442
} else if stepFractionInMinutes <= 10 {
443-
niceFraction = 10 * DateMagnitude.minutesThreshold.lowerBound
443+
niceFraction = 10 * DateMagnitude.minutes.seconds
444444
} else {
445-
niceFraction = 30 * DateMagnitude.minutesThreshold.lowerBound
445+
niceFraction = 30 * DateMagnitude.minutes.seconds
446446
}
447447
return niceFraction
448448
case .hours:
449-
let stepFractionInHours = step / DateMagnitude.hoursThreshold.lowerBound
449+
let stepFractionInHours = step / DateMagnitude.hours.seconds
450450
if stepFractionInHours <= 1 {
451-
niceFraction = 1 * DateMagnitude.hoursThreshold.lowerBound
451+
niceFraction = 1 * DateMagnitude.hours.seconds
452452
} else if stepFractionInHours <= 2 {
453-
niceFraction = 2 * DateMagnitude.hoursThreshold.lowerBound
453+
niceFraction = 2 * DateMagnitude.hours.seconds
454454
} else if stepFractionInHours <= 6 {
455-
niceFraction = 6 * DateMagnitude.hoursThreshold.lowerBound
455+
niceFraction = 6 * DateMagnitude.hours.seconds
456456
} else {
457-
niceFraction = 12 * DateMagnitude.hoursThreshold.lowerBound
457+
niceFraction = 12 * DateMagnitude.hours.seconds
458458
}
459459
return niceFraction
460460
case .days:
461-
let stepFractionInDays = step / DateMagnitude.daysThreshold.lowerBound
461+
let stepFractionInDays = step / DateMagnitude.days.seconds
462462
if stepFractionInDays <= 1 {
463-
niceFraction = 1 * DateMagnitude.daysThreshold.lowerBound
463+
niceFraction = 1 * DateMagnitude.days.seconds
464464
} else if stepFractionInDays <= 2 {
465-
niceFraction = 2 * DateMagnitude.daysThreshold.lowerBound
465+
niceFraction = 2 * DateMagnitude.days.seconds
466466
} else {
467-
niceFraction = 7 * DateMagnitude.daysThreshold.lowerBound
467+
niceFraction = 7 * DateMagnitude.days.seconds
468468
}
469469
return niceFraction
470470
case .months:
471-
let stepFractionInMonths = step / DateMagnitude.monthsThreshold.lowerBound
471+
let stepFractionInMonths = step / DateMagnitude.months.seconds
472472
if stepFractionInMonths <= 1 {
473-
niceFraction = 1 * DateMagnitude.monthsThreshold.lowerBound
473+
niceFraction = 1 * DateMagnitude.months.seconds
474474
} else if stepFractionInMonths <= 2 {
475-
niceFraction = 2 * DateMagnitude.monthsThreshold.lowerBound
475+
niceFraction = 2 * DateMagnitude.months.seconds
476476
} else {
477-
niceFraction = 6 * DateMagnitude.monthsThreshold.lowerBound
477+
niceFraction = 6 * DateMagnitude.months.seconds
478478
}
479479
return niceFraction
480480
case .years:
481-
let stepFractionInYears = step / DateMagnitude.yearsThreshold.lowerBound
481+
let stepFractionInYears = step / DateMagnitude.years.seconds
482482
let yearsMagnitude = floor(log10(stepFractionInYears))
483483
let yearsFraction = stepFractionInYears / pow(10, yearsMagnitude)
484484
if yearsFraction <= 1 {
@@ -494,6 +494,16 @@ public extension Date {
494494
}
495495
}
496496

497+
static func niceExpandDomain(min: Self, max: Self, calendar: Calendar) -> (Self, Self) {
498+
let magnitude = DateMagnitude.magnitudeOfDateRange(min, max)
499+
if let niceMin = min.round(magnitude: magnitude, calendar: calendar),
500+
let niceMax = max.roundUp(magnitude: magnitude, calendar: calendar)
501+
{
502+
return (niceMin, niceMax)
503+
}
504+
return (min, max)
505+
}
506+
497507
static func niceMinStepMax(min: Self, max: Self, ofSize size: Int, calendar: Calendar) -> (Self, Double, Self) {
498508
precondition(size > 1)
499509
let magnitude = DateMagnitude.magnitudeOfDateRange(min, max)

Tests/SwiftVizScaleTests/DateNiceValueTests.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,4 +479,34 @@ final class DateNiceValueTests: XCTestCase {
479479
XCTAssertTrue(resultDates.first! <= dateMin)
480480
XCTAssertTrue(resultDates.last! >= dateMax)
481481
}
482+
483+
func testNiceExpandDomain_days_23() throws {
484+
let (formatter, now) = formatterAndNow()
485+
486+
let dateMin = now
487+
let dateMax = now + 23.1 * DateMagnitude.days.seconds
488+
// before
489+
XCTAssertEqual(formatter.string(from: dateMin), "2022-08-08T22:43:09.011Z")
490+
XCTAssertEqual(formatter.string(from: dateMax), "2022-09-01T01:07:09.011Z")
491+
492+
// after
493+
let (updatedMin, updatedMax) = Date.niceExpandDomain(min: dateMin, max: dateMax, calendar: testCal)
494+
XCTAssertEqual(formatter.string(from: updatedMin), "2022-08-08T00:00:00.000Z")
495+
XCTAssertEqual(formatter.string(from: updatedMax), "2022-09-02T00:00:00.000Z")
496+
}
497+
498+
func testNiceExpandDomain_hours_11() throws {
499+
let (formatter, now) = formatterAndNow()
500+
501+
let dateMin = now
502+
let dateMax = now + 11 * DateMagnitude.hours.seconds
503+
// before
504+
XCTAssertEqual(formatter.string(from: dateMin), "2022-08-08T22:43:09.011Z")
505+
XCTAssertEqual(formatter.string(from: dateMax), "2022-08-09T09:43:09.011Z")
506+
507+
// after
508+
let (updatedMin, updatedMax) = Date.niceExpandDomain(min: dateMin, max: dateMax, calendar: testCal)
509+
XCTAssertEqual(formatter.string(from: updatedMin), "2022-08-08T22:00:00.000Z")
510+
XCTAssertEqual(formatter.string(from: updatedMax), "2022-08-09T10:00:00.000Z")
511+
}
482512
}

Tests/SwiftVizScaleTests/DateScaleTests.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ final class DateScaleTests: XCTestCase {
3333
XCTAssertEqual(updated.domainHigher, now)
3434

3535
let dateSet = [now, now.addingTimeInterval(-600), now.addingTimeInterval(600)]
36-
let setUpdated = updated.domain(dateSet)
36+
let setUpdated = updated.domain(dateSet, nice: false)
3737
XCTAssertEqual(setUpdated.domainLower, now.addingTimeInterval(-600))
3838
XCTAssertEqual(setUpdated.domainHigher, now.addingTimeInterval(600))
39+
40+
let setNiceUpdated = updated.domain(dateSet, nice: true)
41+
XCTAssertEqual(setNiceUpdated.domainLower, now.addingTimeInterval(-600))
42+
XCTAssertEqual(setNiceUpdated.domainHigher, now.addingTimeInterval(660))
3943
}
4044

4145
func testTransformModifier() throws {

0 commit comments

Comments
 (0)