Add timeline cursor label

pull/37/head
Varun Patil 2022-08-18 01:55:12 +00:00
parent f65c54f104
commit c58726d81a
1 changed files with 62 additions and 13 deletions

View File

@ -53,13 +53,15 @@
@touchmove="timelineTouch"
@mouseleave="timelineLeave"
@mousedown="timelineClick">
<span class="cursor"
<span class="cursor st"
v-bind:style="{ top: timelineCursorY + 'px' }"></span>
<span class="cursor"
v-bind:style="{ transform: `translateY(${timelineHoverCursorY}px)` }"></span>
<span class="cursor hv"
v-bind:style="{ transform: `translateY(${timelineHoverCursorY}px)` }">
{{ timelineHoverCursorText }}
</span>
<div v-for="tick of timelineTicks" :key="tick.dayId" class="tick"
v-bind:style="{ top: Math.floor((tick.topS + tick.top * rowHeight) * timelineHeight / viewHeight) + 'px' }">
v-bind:style="{ top: tick.topC + 'px' }">
<span v-if="tick.text">{{ tick.text }}</span>
<span v-else class="dash"></span>
</div>
@ -99,6 +101,8 @@ export default {
timelineCursorY: 0,
/** Timeline hover cursor top */
timelineHoverCursorY: -5,
/** Timeline hover cursor text */
timelineHoverCursorText: "",
/** Current start index */
currentStart: 0,
@ -174,6 +178,11 @@ export default {
handleViewSizeChange() {
setTimeout(() => {
this.viewHeight = this.$refs.scroller.$refs.wrapper.clientHeight;
// Compute timeline tick positions
for (const tick of this.timelineTicks) {
tick.topC = Math.floor((tick.topS + tick.top * this.rowHeight) * this.timelineHeight / this.viewHeight);
}
}, 0);
},
@ -185,6 +194,7 @@ export default {
scrollPositionChange(event) {
if (event) {
this.timelineCursorY = event.target.scrollTop * this.timelineHeight / this.viewHeight;
this.timelineMoveHoverCursor(this.timelineCursorY);
}
if (this.scrollTimer) {
@ -257,8 +267,9 @@ export default {
// Ticks
let currTopRow = 0;
let currTopStatic = 0;
let prevYear = new Date().getUTCFullYear();
let prevMonth = new Date().getUTCMonth();
let prevYear = 9999;
let prevMonth = 0;
const thisYear = new Date().getFullYear();
for (const [dayIdx, day] of data.entries()) {
day.count = Number(day.count);
@ -280,11 +291,18 @@ export default {
const dtYear = dateTaken.getUTCFullYear();
const dtMonth = dateTaken.getUTCMonth()
if (Number.isInteger(day.day_id) && (dtMonth !== prevMonth || dtYear !== prevYear)) {
// Format dateTaken as MM YYYY
const dateTimeFormat = new Intl.DateTimeFormat('en-US', { month: 'short' });
const monthName = dateTimeFormat.formatToParts(dateTaken)[0].value;
// Create tick
this.timelineTicks.push({
dayId: day.id,
top: currTopRow,
topS: currTopStatic,
text: dtYear === prevYear ? undefined : dtYear,
topC: 0,
text: (dtYear === prevYear || dtYear === thisYear) ? undefined : dtYear,
mText: `${monthName} ${dtYear}`,
});
}
prevMonth = dtMonth;
@ -402,17 +420,32 @@ export default {
};
},
timelineMoveHoverCursor(y) {
this.timelineHoverCursorY = y;
// Get index of previous tick
let idx = this.timelineTicks.findIndex(t => t.topC > y);
if (idx >= 1) {
idx = idx - 1;
} else if (idx === -1 && this.timelineTicks.length > 0) {
idx = this.timelineTicks.length - 1;
} else {
return;
}
this.timelineHoverCursorText = this.timelineTicks[idx].mText;
},
/** Handle mouse hover on right timeline */
timelineHover(event) {
if (event.buttons) {
this.timelineClick(event);
}
this.timelineHoverCursorY = event.offsetY;
this.timelineMoveHoverCursor(event.offsetY);
},
/** Handle mouse leave on right timeline */
timelineLeave() {
this.timelineHoverCursorY = -5;
this.timelineMoveHoverCursor(this.timelineCursorY);
},
/** Handle mouse click on right timeline */
@ -573,7 +606,6 @@ export default {
height: 100%;
width: 40px;
top: 0; right: 0;
overflow: hidden;
cursor: ns-resize;
opacity: 0;
transition: opacity .2s ease-in-out;
@ -589,6 +621,7 @@ export default {
color: black;
right: 5px;
transform: translateY(-50%);
z-index: 1;
}
.timeline-scroll .tick .dash {
@ -602,9 +635,25 @@ export default {
position: absolute;
pointer-events: none;
right: 5px;
height: 2px;
background-color: var(--color-primary);
border-radius: 4px;
width: 100%;
min-width: 100%;
min-height: 2px;
}
.timeline-scroll .cursor.st {
opacity: 0;
}
.timeline-scroll:hover .cursor.st {
opacity: 1;
}
.timeline-scroll .cursor.hv {
background-color: rgba(255, 255, 255, 0.8);
padding: 2px 5px;
border-top: 2px solid var(--color-primary);
border-radius: 2px;
width: auto;
white-space: nowrap;
z-index: 100;
}
</style>