From e5d4b142f6f7eb21c2b55edfbd472f503e7f3b89 Mon Sep 17 00:00:00 2001
From: Terry Truong <terry06890@gmail.com>
Date: Sat, 7 Jan 2023 12:37:05 +1100
Subject: At each scale, always display a unit that includes MAX_DATE

Without this, with a MAX_DATE of, say 2000/1/1, zooming out to
scale 1e9 won't show events after 1 AD.
---
 src/components/TimeLine.vue | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

(limited to 'src/components/TimeLine.vue')

diff --git a/src/components/TimeLine.vue b/src/components/TimeLine.vue
index 3172e80..823fe86 100644
--- a/src/components/TimeLine.vue
+++ b/src/components/TimeLine.vue
@@ -26,7 +26,7 @@
 		<line :stroke="store.color.alt" stroke-width="2px" x1="-1" y1="0" x2="2" y2="0" :style="mainlineStyles"/>
 		<!-- Tick markers -->
 		<template v-for="tick in ticks" :key="tick.date.toInt()">
-			<line v-if="tick.major && (tick.date.equals(MIN_DATE, scale) || tick.date.equals(MAX_DATE, scale))"
+			<line v-if="tick.major && (tick.date.equals(MIN_DATE, scale) || tick.date.equals(maxDateOnScale, scale))"
 				:x1="vert ? -store.endTickSz / 2 : 0" :y1="vert ? 0 : -store.endTickSz / 2"
 				:x2="vert ?  store.endTickSz / 2 : 0" :y2="vert ? 0 :  store.endTickSz / 2"
 				:stroke="store.color.alt" :stroke-width="`${store.endTickSz}px`"
@@ -235,6 +235,7 @@ function initScale(){ // Initialises to smallest usable scale
 // Tick data
 const tickLabelMargin = computed(() => props.vert ? 20 : 30); // Distance from label to mainline
 const tickLabelWidth = computed(() => store.mainlineBreadth - store.largeTickLen / 2 - tickLabelMargin.value);
+const maxDateOnScale = computed(() => dateToScaleDate(MAX_DATE, scale.value, true));
 class Tick {
 	date: HistDate;
 	major: boolean; // False if tick is on the minor scale
@@ -314,7 +315,7 @@ const ticks = computed((): Tick[] => {
 	// Get after-endDate ticks (including end-offset ticks and hidden ticks)
 	let endDateOffset = ticks[ticks.length - 1].offset;
 	for (let i = 0; i < panUnits + Math.ceil(endOffset.value); i++){
-		if (MAX_DATE.equals(date, scale.value)){
+		if (maxDateOnScale.value.equals(date, scale.value)){
 			break;
 		}
 		// Add minor ticks
@@ -349,7 +350,7 @@ const ticks = computed((): Tick[] => {
 			offset = ticks[ticks.length - 1].offset;
 			for (let i = 0; i < (zoomUnits - panUnits) / unitsPerZoomedUnit; i++){
 				date = stepDate(date, zoomedScale);
-				if (MAX_DATE.isEarlier(date, scale.value)){
+				if (maxDateOnScale.value.isEarlier(date, scale.value)){
 					break;
 				}
 				ticksAfter.push(new Tick(date, true, offset + (i + 1) * unitsPerZoomedUnit));
@@ -731,7 +732,7 @@ function panTimeline(scrollRatio: number){
 		getMovedBounds(startOffset.value, endOffset.value, chgUnits, chgUnits);
 	if (scrollRatio > 0){
 		while (true){
-			if (newEnd.equals(MAX_DATE, scale.value)){
+			if (newEnd.equals(maxDateOnScale.value, scale.value)){
 				// Pan up to an offset of store.defaultEndTickOffset
 				if (store.defaultEndTickOffset == endOffset.value){
 					console.log('Reached maximum date limit');
@@ -824,7 +825,7 @@ function panTimeline(scrollRatio: number){
 function zoomTimeline(zoomRatio: number, ignorePointer=false){
 	if (zoomRatio > 1
 			&& startDate.value.equals(MIN_DATE, scale.value)
-			&& endDate.value.equals(MAX_DATE, scale.value)){
+			&& endDate.value.equals(maxDateOnScale.value, scale.value)){
 		console.log('Reached upper scale limit');
 		return;
 	}
@@ -875,7 +876,7 @@ function zoomTimeline(zoomRatio: number, ignorePointer=false){
 			newNumUnits += 1;
 		}
 		while (numEndSteps > 0){
-			if (MAX_DATE.equals(newEnd, scale.value)){
+			if (maxDateOnScale.value.equals(newEnd, scale.value)){
 				newEndOffset = store.defaultEndTickOffset;
 				break;
 			}
@@ -975,7 +976,7 @@ function zoomTimeline(zoomRatio: number, ignorePointer=false){
 					console.log('Unable to zoom into range where month/day scale is invalid');
 					return;
 				}
-				if (newStart.isEarlier(MIN_DATE, newScale) || MAX_DATE.isEarlier(newEnd, newScale)){
+				if (newStart.isEarlier(MIN_DATE, newScale) || maxDateOnScale.value.isEarlier(newEnd, newScale)){
 					console.log('Disallowing zooming in beyond min/max dates');
 					return;
 				}
@@ -1146,15 +1147,15 @@ watch(() => props.searchTarget, () => {
 			targetStart = MIN_DATE;
 		}
 		let targetEnd = stepDate(targetStart, tempScale, {count: startEndDiff});
-		if (MAX_DATE.isEarlier(targetEnd)){
+		if (maxDateOnScale.value.isEarlier(targetEnd)){
 			if (targetStart != MIN_DATE){
 				targetStart = stepDate(targetStart, tempScale,
-					{forward: false, count: getUnitDiff(targetEnd, MAX_DATE, tempScale)});
+					{forward: false, count: getUnitDiff(targetEnd, maxDateOnScale.value, tempScale)});
 				if (targetStart.isEarlier(MIN_DATE)){
 					targetStart = MIN_DATE;
 				}
 			}
-			targetEnd = MAX_DATE;
+			targetEnd = maxDateOnScale.value;
 		}
 		// Jump to range
 		startDate.value = targetStart;
-- 
cgit v1.2.3

