diff options
| -rw-r--r-- | src/components/TimeLine.vue | 69 | ||||
| -rw-r--r-- | src/lib.ts | 13 |
2 files changed, 47 insertions, 35 deletions
diff --git a/src/components/TimeLine.vue b/src/components/TimeLine.vue index ccf9d9b..c70fbf9 100644 --- a/src/components/TimeLine.vue +++ b/src/components/TimeLine.vue @@ -64,7 +64,7 @@ import IconButton from './IconButton.vue'; import CloseIcon from './icon/CloseIcon.vue'; // Other import {WRITING_MODE_HORZ, MIN_DATE, MAX_DATE, MONTH_SCALE, DAY_SCALE, SCALES, - MIN_CAL_YEAR, HistDate, CalDate, stepDate, getScaleRatio, getUnitDiff, getDaysInMonth, + MIN_CAL_YEAR, HistDate, CalDate, stepDate, getScaleRatio, getNumSubUnits, getUnitDiff, getDaysInMonth, moduloPositive, TimelineState, HistEvent, getImagePath} from '../lib'; import {useStore} from '../store'; import {RBTree} from '../rbtree'; @@ -157,7 +157,6 @@ const hasMinorScale = computed(() => { // If true, display subset of ticks of ne } return (availLen.value / numUnits) >= 2 * store.minTickSep; }); -const minorScale = computed(() => hasMinorScale.value ? SCALES[scaleIdx.value + 1] : scale.value); if (props.initialState.startOffset != null){ startOffset.value = props.initialState.startOffset as number; } @@ -231,28 +230,43 @@ class Tick { } } function getNumDisplayUnits({inclOffsets=true} = {}): number { // Get num major units in display range - let unitDiff = getUnitDiff(startDate.value, endDate.value, scale.value); + let unitDiff = Math.ceil(getUnitDiff(startDate.value, endDate.value, scale.value)); + // Note: Rounding up due to cases like 1 CE to 10 CE with 10-year scale if (inclOffsets){ unitDiff += startOffset.value + endOffset.value; } return unitDiff; } +function getMinorTicks(date: HistDate, scaleIdx: number, majorUnitSz: number, majorOffset: number): Tick[] { + // For a major unit, returns an array specifying minor ticks to show + if (!hasMinorScale.value){ + return []; + } + let minorTicks: Tick[] = []; + let numMinorUnits = getNumSubUnits(date, scaleIdx); + let minorUnitSz = majorUnitSz / numMinorUnits; + let minStep = Math.ceil(store.minTickSep / minorUnitSz); + let stepFrac = numMinorUnits / Math.floor(numMinorUnits / minStep); + // Iterate through fractional indexes, using rounded differences to step dates + let idxFrac = stepFrac; + let idx = Math.floor(idxFrac); + let idxChg = idx; + while (Math.ceil(idxFrac) < numMinorUnits){ + date = stepDate(date, SCALES[scaleIdx + 1], {count: idxChg}); + minorTicks.push(new Tick(date, false, majorOffset + idx / numMinorUnits)) + idxFrac += stepFrac; + idxChg = Math.floor(idxFrac) - idx; + idx = Math.floor(idxFrac); + } + return minorTicks; +} const ticks = computed((): Tick[] => { let ticks: Tick[] = []; if (!mounted.value){ return ticks; } let numUnits = getNumDisplayUnits(); - // Determine minor-tick params - let minorUnitsPerMajor = getScaleRatio(minorScale.value, scale.value, true); - let minorTickStep = 0;// Number of minor units between minor ticks - let minorTicksPerMajor = 0;// Minor ticks per major tick - if (hasMinorScale.value){ - let majorUnitSz = availLen.value / getNumDisplayUnits(); - let minorUnitSz = majorUnitSz / minorUnitsPerMajor; - minorTickStep = Math.ceil(store.minTickSep / minorUnitSz); // TODO: Account for minorUnitSz being larger? - minorTicksPerMajor = Math.ceil(minorUnitsPerMajor / minorTickStep) - 1; - } + let majorUnitSz = availLen.value / numUnits; // Get before-startDate ticks (including start-offset ticks and hidden ticks) let panUnits = Math.floor(getNumDisplayUnits() * store.scrollRatio); // Potential shift distance upon a pan action let date = startDate.value; @@ -262,13 +276,7 @@ const ticks = computed((): Tick[] => { } date = stepDate(date, scale.value, {forward: false}); // Add minor ticks - let minorTicks: Tick[] = []; - let tempDate = date; - for (let j = 0; j < minorTicksPerMajor; j++){ - tempDate = stepDate(tempDate, minorScale.value, {count: minorTickStep}); - let offset = startOffset.value - (i + 1) + (j + 1) * minorTickStep / minorUnitsPerMajor; - minorTicks.push(new Tick(tempDate, false, offset)); - } + let minorTicks = getMinorTicks(date, scaleIdx.value, majorUnitSz, startOffset.value - (i + 1)); minorTicks.reverse(); ticks.push(...minorTicks); // Add major date @@ -283,14 +291,9 @@ const ticks = computed((): Tick[] => { if (i == numMajorUnits){ break; } - // Add minor ticks - let nextMajor = stepDate(date, scale.value); - for (let j = 0; j < minorTicksPerMajor; j++){ - date = stepDate(date, minorScale.value, {count: minorTickStep}); - let offset = startOffset.value + i + (j + 1) * minorTickStep / minorUnitsPerMajor; - ticks.push(new Tick(date, false, offset)); - } - date = nextMajor; + let minorTicks = getMinorTicks(date, scaleIdx.value, majorUnitSz, startOffset.value + i); + ticks.push(...minorTicks); + date = stepDate(date, scale.value); } // Get after-endDate ticks (including end-offset ticks and hidden ticks) let endDateOffset = ticks[ticks.length - 1].offset; @@ -298,15 +301,11 @@ const ticks = computed((): Tick[] => { if (MAX_DATE.equals(date, scale.value)){ break; } - let nextMajor = stepDate(date, scale.value); // Add minor ticks - for (let j = 0; j < minorTicksPerMajor; j++){ - date = stepDate(date, minorScale.value, {count: minorTickStep}); - let offset = endDateOffset + i + (j + 1) * minorTickStep / minorUnitsPerMajor; - ticks.push(new Tick(date, false, offset)); - } + let minorTicks = getMinorTicks(date, scaleIdx.value, majorUnitSz, endDateOffset + i); + ticks.push(...minorTicks); // Add major date - date = nextMajor; + date = stepDate(date, scale.value); ticks.push(new Tick(date, true, endDateOffset + (i + 1))); } // Get hidden ticks that might transition in after zooming @@ -451,6 +451,19 @@ export function getScaleRatio(scale: number, scale2: number, lowerVal=false){ } return scale2 / scale; } +export function getNumSubUnits(date: HistDate, scaleIdx: number){ + // Returns number of sub-units for a unit starting at 'date' on scale for 'scaleIdx' + const scale = SCALES[scaleIdx] + if (scale == DAY_SCALE){ + throw new Error('Cannot get sub-units for DAY_SCALE unit'); + } else if (scale == MONTH_SCALE){ + return getDaysInMonth(date.year, date.month); // Note: Intentionally not checking with MIN_CAL_YEAR + } else if (scale == 1){ + return 12; + } else { + return scale / SCALES[scaleIdx + 1] - (date.year == 1 ? 1 : 0); // Account for lack of 0 CE + } +} export function getUnitDiff(date: HistDate, date2: HistDate, scale: number): number { if (scale == DAY_SCALE){ return date.getDayDiff(date2); |
