diff options
| author | Terry Truong <terry06890@gmail.com> | 2022-10-20 15:31:05 +1100 |
|---|---|---|
| committer | Terry Truong <terry06890@gmail.com> | 2022-10-20 15:31:05 +1100 |
| commit | 83366605d1bd43c245c4c110fadfd1a6fd05d3c2 (patch) | |
| tree | a7d0352d2a4d4e14b8113dcfdf28d06a06af20d4 /src | |
| parent | f09bfa345519f7d070ae9c7474ef8b4f91b22bae (diff) | |
Add gcal to client-side HistDates
Add YearDate and CalDate
Restrict non-calendar HistDates to years before 4713 BC
Diffstat (limited to 'src')
| -rw-r--r-- | src/App.vue | 8 | ||||
| -rw-r--r-- | src/components/TimeLine.vue | 7 | ||||
| -rw-r--r-- | src/lib.ts | 74 | ||||
| -rw-r--r-- | src/store.ts | 6 |
4 files changed, 63 insertions, 32 deletions
diff --git a/src/App.vue b/src/App.vue index 4eed256..c3cf6bf 100644 --- a/src/App.vue +++ b/src/App.vue @@ -39,7 +39,7 @@ import PlusIcon from './components/icon/PlusIcon.vue'; import SettingsIcon from './components/icon/SettingsIcon.vue'; import HelpIcon from './components/icon/HelpIcon.vue'; // Other -import {HistDate, TimelineState, HistEvent, queryServer, HistEventJson, jsonToHistEvent, cmpHistEvent, +import {HistDate, YearDate, TimelineState, HistEvent, queryServer, HistEventJson, jsonToHistEvent, cmpHistEvent, timeout} from './lib'; import {useStore} from './store'; import {RBTree, rbtree_shallow_copy} from './rbtree'; @@ -109,7 +109,7 @@ function cmpDatePairs(datePair1: [HistDate, HistDate], datePair2: [HistDate, His } function isExhaustedRange(startDate: HistDate, endDate: HistDate): boolean { // Check if input range is contained in a stored exhausted range - let itr = exhaustedRanges.lowerBound([startDate, new HistDate(1)]); + let itr = exhaustedRanges.lowerBound([startDate, new YearDate()]); let datePair = itr.data(); if (datePair == null){ datePair = itr.prev(); @@ -129,7 +129,7 @@ function isExhaustedRange(startDate: HistDate, endDate: HistDate): boolean { function addExhaustedRange(startDate: HistDate, endDate: HistDate){ let rangesToRemove: HistDate[] = []; // Holds starts of ranges to remove // Find ranges to remove - let itr = exhaustedRanges.lowerBound([startDate, new HistDate(1)]); + let itr = exhaustedRanges.lowerBound([startDate, new YearDate()]); let prevRange = itr.prev(); if (prevRange != null){ // Check for start-overlapping range if (prevRange[1].isEarlier(startDate)){ @@ -153,7 +153,7 @@ function addExhaustedRange(startDate: HistDate, endDate: HistDate){ } // Remove included/overlapping ranges for (let start of rangesToRemove){ - exhaustedRanges.remove([start, new HistDate(1)]); + exhaustedRanges.remove([start, new YearDate()]); } // Add possibly-merged range if (prevRange != null){ diff --git a/src/components/TimeLine.vue b/src/components/TimeLine.vue index 5aec9b2..8a6ddc4 100644 --- a/src/components/TimeLine.vue +++ b/src/components/TimeLine.vue @@ -63,9 +63,9 @@ import IconButton from './IconButton.vue'; // Icons import MinusIcon from './icon/MinusIcon.vue'; // Other -import {WRITING_MODE_HORZ, MIN_DATE, MAX_DATE, MONTH_SCALE, DAY_SCALE, SCALES, MIN_CAL_DATE, - HistDate, stepDate, inDateScale, getScaleRatio, getUnitDiff, getDaysInMonth, moduloPositive, TimelineState, - HistEvent, getImagePath} from '../lib'; +import {WRITING_MODE_HORZ, MIN_DATE, MAX_DATE, MONTH_SCALE, DAY_SCALE, SCALES, + MIN_CAL_YEAR, HistDate, CalDate, stepDate, inDateScale, getScaleRatio, getUnitDiff, getDaysInMonth, + moduloPositive, TimelineState, HistEvent, getImagePath} from '../lib'; import {useStore} from '../store'; import {RBTree} from '../rbtree'; @@ -132,6 +132,7 @@ const mainlineOffset = computed(() => { // Distance mainline-area line to side o // Timeline data const ID = props.initialState.id as number; +const MIN_CAL_DATE = new CalDate(MIN_CAL_YEAR, 1, 1); const startDate = ref(props.initialState.startDate); // Earliest date to display const endDate = ref(props.initialState.endDate); const startOffset = ref(store.defaultEndTickOffset); // Fraction of a scale unit before startDate to show @@ -75,11 +75,14 @@ export function getDaysInMonth(year: number, month: number){ } // For date representation +export const MIN_CAL_YEAR = -4713; // Year after which months/day scales are usable export class HistDate { + gcal: boolean | null; year: number; month: number; day: number; - constructor(year: number, month=1, day=1){ + constructor(gcal: boolean | null, year: number, month: number, day: number){ + this.gcal = gcal; this.year = year; this.month = month; this.day = day; @@ -93,15 +96,6 @@ export class HistDate { return Math.floor(this.year / scale) == Math.floor(other.year / scale); } } - cmp(other: HistDate, scale=DAY_SCALE){ - if (this.isEarlier(other, scale)){ - return -1; - } else if (!this.equals(other, scale)){ - return 1; - } else { - return 0; - } - } isEarlier(other: HistDate, scale=DAY_SCALE){ const yearlyScale = scale != DAY_SCALE && scale != MONTH_SCALE; const thisYear = yearlyScale ? Math.floor(this.year / scale) : this.year; @@ -116,14 +110,23 @@ export class HistDate { } } } + cmp(other: HistDate, scale=DAY_SCALE){ + if (this.isEarlier(other, scale)){ + return -1; + } else if (!this.equals(other, scale)){ + return 1; + } else { + return 0; + } + } toInt(){ return this.day + this.month * 50 + this.year * 1000; } toString(){ - if (this.isEarlier(MIN_CAL_DATE)){ - return `${this.year}`; - } else { + if (this.gcal != null){ return `${this.year}-${this.month}-${this.day}`; + } else { + return `${this.year}`; } } toDisplayString(){ @@ -161,7 +164,7 @@ export class HistDate { const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; return monthNames[this.month - 1]; } else { - if (this.day == 1){ // TODO: Show instead of just month name when at day-scale? + if (this.day == 1){ return '1st'; } else if (this.day == 2){ return '2nd'; @@ -172,7 +175,7 @@ export class HistDate { } } } - getDayDiff(other: HistDate){ + getDayDiff(other: HistDate){ // Assumes neither date has gcal=null const jdn2 = gregorianToJdn(this.year, this.month, this.day); const jdn1 = gregorianToJdn(other.year, other.month, other.day); return Math.abs(jdn1 - jdn2); @@ -201,15 +204,38 @@ export class HistDate { return yearDiff; } clone(){ - return new HistDate(this.year, this.month, this.day); + return new HistDate(this.gcal, this.year, this.month, this.day); + } +} +export class YearDate extends HistDate { + declare gcal: null; + declare year: number; + declare month: 1; + declare day: 1; + constructor(year=MIN_CAL_YEAR-1){ + if (year >= MIN_CAL_YEAR){ + throw new Error(`Year must be before ${MIN_CAL_YEAR}`); + } + super(null, year, 1, 1); + } +} +export class CalDate extends HistDate { + declare gcal: boolean; + declare year: number; + declare month: number; + declare day: number; + constructor(year: number, month: number, day: number, gcal=true){ + if (year < MIN_CAL_YEAR){ + throw new Error(`Year must not be before ${MIN_CAL_YEAR}`); + } + super(gcal, year, month, day); } } // Timeline parameters const currentDate = new Date(); -export const MIN_DATE = new HistDate(-13.8e9); -export const MAX_DATE = new HistDate(currentDate.getFullYear(), currentDate.getMonth() + 1, currentDate.getDate()); -export const MIN_CAL_DATE = new HistDate(-4700, 1, 1); // Date after which months/day scales are usable +export const MIN_DATE = new YearDate(-13.8e9); +export const MAX_DATE = new CalDate(currentDate.getFullYear(), currentDate.getMonth() + 1, currentDate.getDate()); export const MONTH_SCALE = -1; export const DAY_SCALE = -2; export const SCALES = [1e9, 1e8, 1e7, 1e6, 1e5, 1e4, 1e3, 100, 10, 1, MONTH_SCALE, DAY_SCALE]; @@ -412,8 +438,8 @@ export function getImagePath(imgId: number): string { export type HistDateJson = { gcal: boolean | null, year: number, - month: number | null, - day: number | null, + month: number, + day: number, } export type HistEventJson = { id: number, @@ -427,7 +453,11 @@ export type HistEventJson = { pop: number, } export function jsonToHistDate(json: HistDateJson){ - return new HistDate(json.year, json.month == null ? 1 : json.month, json.day == null ? 1 : json.day); + if (json.gcal == null){ + return new YearDate(json.year); + } else { + return new CalDate(json.year, json.month, json.day, json.gcal); + } } export function jsonToHistEvent(json: HistEventJson){ return { diff --git a/src/store.ts b/src/store.ts index 7cf815f..66d73ac 100644 --- a/src/store.ts +++ b/src/store.ts @@ -3,7 +3,7 @@ */ import {defineStore} from 'pinia'; -import {HistDate} from './lib'; +import {CalDate} from './lib'; export const useStore = defineStore('store', { state: () => { @@ -37,8 +37,8 @@ export const useStore = defineStore('store', { zoomRatio: 1.5, // Ratio of timeline expansion upon zooming out dragInertia: 0.1, // Multiplied by final-drag-speed (pixels-per-sec) to get extra scroll distance // - initialStartDate: new HistDate(1900, 1, 1), - initialEndDate: new HistDate(2000, 1, 1), + initialStartDate: new CalDate(1900, 1, 1), + initialEndDate: new CalDate(2000, 1, 1), color, transitionDuration: 300, }; |
