aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTerry Truong <terry06890@gmail.com>2023-01-07 12:37:05 +1100
committerTerry Truong <terry06890@gmail.com>2023-01-07 12:37:05 +1100
commite5d4b142f6f7eb21c2b55edfbd472f503e7f3b89 (patch)
tree7a91ccd3d970dfc9e154ca498c36a7870d4b8d39
parentcd890bc47df00f16c54755549314cd7e15ec3219 (diff)
At each scale, always display a unit that includes MAX_DATEunit-after-max
Without this, with a MAX_DATE of, say 2000/1/1, zooming out to scale 1e9 won't show events after 1 AD.
-rw-r--r--src/components/TimeLine.vue21
-rw-r--r--src/lib.ts23
-rw-r--r--tests/lib.test.ts5
3 files changed, 36 insertions, 13 deletions
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;
diff --git a/src/lib.ts b/src/lib.ts
index 3b0bc68..03b443d 100644
--- a/src/lib.ts
+++ b/src/lib.ts
@@ -582,14 +582,31 @@ export function dateToUnit(date: HistDate, scale: number): number {
}
}
}
-export function dateToScaleDate(date: HistDate, scale: number): HistDate {
+export function dateToScaleDate(date: HistDate, scale: number, upward=false): HistDate {
// Returns a date representing the unit on 'scale' that 'date' is within
if (scale == DAY_SCALE){
return new CalDate(date.year, date.month, date.day);
} else if (scale == MONTH_SCALE){
- return new CalDate(date.year, date.month, 1);
+ if (upward && date.day > 1){
+ return stepDate(new CalDate(date.year, date.month, 1), MONTH_SCALE);
+ } else {
+ return new CalDate(date.year, date.month, 1);
+ }
+ } else if (scale == 1){
+ if (upward && date.month > 1){
+ return stepDate(new CalDate(date.year, 1, 1), 1);
+ } else {
+ if (date.year < MIN_CAL_YEAR){
+ return new YearDate(date.year);
+ } else {
+ return new CalDate(date.year == 0 ? 1 : date.year, 1, 1);
+ }
+ }
} else {
- const year = Math.floor(date.year / scale) * scale;
+ let year = Math.floor(date.year / scale) * scale;
+ if (upward && moduloPositive(date.year, scale) > 0){
+ year += scale;
+ }
if (year < MIN_CAL_YEAR){
return new YearDate(year);
} else {
diff --git a/tests/lib.test.ts b/tests/lib.test.ts
index c87627c..6bf3d89 100644
--- a/tests/lib.test.ts
+++ b/tests/lib.test.ts
@@ -156,11 +156,16 @@ test('dateToUnit', () => {
})
test('dateToScaleDate', () => {
expect(dateToScaleDate(new CalDate(2013, 10, 3), DAY_SCALE)).toEqual(new CalDate(2013, 10, 3))
+ expect(dateToScaleDate(new CalDate(2013, 10, 3), DAY_SCALE, true)).toEqual(new CalDate(2013, 10, 3))
expect(dateToScaleDate(new CalDate(2013, 10, 3, false), MONTH_SCALE)).toEqual(new CalDate(2013, 10, 1))
+ expect(dateToScaleDate(new CalDate(2013, 10, 3), MONTH_SCALE, true)).toEqual(new CalDate(2013, 11, 1))
expect(dateToScaleDate(new CalDate(2013, 10, 3), 1)).toEqual(new CalDate(2013, 1, 1))
+ expect(dateToScaleDate(new CalDate(2013, 10, 3), 1, true)).toEqual(new CalDate(2014, 1, 1))
expect(dateToScaleDate(new CalDate(2013, 10, 3), 1e3)).toEqual(new CalDate(2000, 1, 1))
+ expect(dateToScaleDate(new CalDate(2013, 10, 3), 1e3, true)).toEqual(new CalDate(3000, 1, 1))
expect(dateToScaleDate(new CalDate(2013, 10, 3), 1e4)).toEqual(new CalDate(1, 1, 1))
expect(dateToScaleDate(new YearDate(-1222333), 1e6)).toEqual(new YearDate(-2000000))
+ expect(dateToScaleDate(new YearDate(-1222333), 1e6, true)).toEqual(new YearDate(-1000000))
})
test('DateRangeTree', () => {