aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/App.vue8
-rw-r--r--src/components/TimeLine.vue34
2 files changed, 25 insertions, 17 deletions
diff --git a/src/App.vue b/src/App.vue
index 442d3cb..e836fbf 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -84,7 +84,7 @@ function onTimelineChg(state: TimelineState, idx: number){
}
// For timeline addition/removal
-const MIN_TIMELINE_BREADTH = 80 + 10 * 2 + 115; // TODO: Link with constants in components/TimeLine.vue
+const MIN_TIMELINE_BREADTH = 80 + 10 * 2 + 120; // TODO: Link with constants in components/TimeLine.vue
function onTimelineAdd(){
if (vert.value && contentWidth.value / (timelines.value.length + 1) < MIN_TIMELINE_BREADTH ||
!vert.value && contentHeight.value / (timelines.value.length + 1) < MIN_TIMELINE_BREADTH){
@@ -192,6 +192,7 @@ function reduceEvents(){
}
// For getting events from server
const EVENT_REQ_LIMIT = 30;
+const REQ_EXCLS_LIMIT = 100;
let pendingReq = false; // Used to serialise event-req handling
async function onEventReq(startDate: HistDate, endDate: HistDate){
while (pendingReq){
@@ -214,6 +215,11 @@ async function onEventReq(startDate: HistDate, endDate: HistDate){
}
existingEventIds.push(event.id);
}
+ if (existingEventIds.length > REQ_EXCLS_LIMIT){
+ console.log('WARNING: Exceeded request exclusions limit');
+ pendingReq = false;
+ return;
+ }
// Get events from server
let urlParams = new URLSearchParams({
type: 'events',
diff --git a/src/components/TimeLine.vue b/src/components/TimeLine.vue
index 03097d1..a175681 100644
--- a/src/components/TimeLine.vue
+++ b/src/components/TimeLine.vue
@@ -40,12 +40,12 @@
</svg>
<!-- Events -->
<div v-for="id in idToPos.keys()" :key="id" class="absolute animate-fadein" :style="eventStyles(id)">
+ <!-- Image -->
+ <div class="rounded-full border border-yellow-500" :style="eventImgStyles(id)"></div>
<!-- Label -->
<div class="text-center text-stone-100 text-sm whitespace-nowrap text-ellipsis overflow-hidden">
{{idToEvent.get(id)!.title}}
</div>
- <!-- Image -->
- <div class="rounded-full border border-yellow-500" :style="eventImgStyles(id)"></div>
</div>
<!-- Buttons -->
<icon-button :size="30" class="absolute top-2 right-2"
@@ -117,7 +117,7 @@ onMounted(() => resizeObserver.observe(rootRef.value as HTMLElement));
//
const MAINLINE_WIDTH = 80; // Breadth of mainline area (including ticks and labels)
const EVENT_IMG_SZ = 100; // Width/height of event images
-const EVENT_LABEL_HEIGHT = 15;
+const EVENT_LABEL_HEIGHT = 20;
const eventWidth = computed(() => EVENT_IMG_SZ);
const eventHeight = computed(() => EVENT_IMG_SZ + EVENT_LABEL_HEIGHT);
const eventMajorSz = computed(() => props.vert ? eventHeight.value : eventWidth.value);
@@ -313,36 +313,36 @@ const idToPos = computed(() => {
}
let map: Map<number, [number, number, number, number]> = new Map(); // Maps visible event IDs to x/y/w/h
// Do basic grid-like layout
- let posX = SPACING, posY = SPACING;
+ let minorOffset = SPACING, majorOffset = SPACING; // Holds x and y for event element (or y and x if !props.vert)
let full = false;
for (let event of idToEvent.value.values()){
- // Layout as if props.vert
- if (posY + eventMajorSz.value + SPACING > availLen.value){ // If at end of column
- posY = SPACING;
- posX += eventMinorSz.value + SPACING;
+ // Check if at end of column (or row if !props.vert)
+ if (majorOffset + eventMajorSz.value + SPACING > availLen.value){
+ majorOffset = SPACING;
+ minorOffset += eventMinorSz.value + SPACING;
// If finished last row
- if (posX + eventMinorSz.value + SPACING > availBreadth.value){
+ if (minorOffset + eventMinorSz.value + SPACING > availBreadth.value){
full = true;
break;
}
}
// Avoid collision with timeline
if (!sideMainline.value){
- if (posX <= availBreadth.value / 2 + MAINLINE_WIDTH / 2 + SPACING &&
- posX + eventMinorSz.value >= availBreadth.value / 2 - MAINLINE_WIDTH / 2 - SPACING){
- posX = availBreadth.value / 2 + MAINLINE_WIDTH / 2 + SPACING;
+ if (minorOffset <= availBreadth.value / 2 + MAINLINE_WIDTH / 2 + SPACING &&
+ minorOffset + eventMinorSz.value >= availBreadth.value / 2 - MAINLINE_WIDTH / 2 - SPACING){
+ minorOffset = availBreadth.value / 2 + MAINLINE_WIDTH / 2 + SPACING;
}
- } else if (posX + eventMinorSz.value + SPACING > mainlineOffset.value){
+ } else if (minorOffset + eventMinorSz.value + SPACING > mainlineOffset.value){
break;
}
// Add coords
if (props.vert){
- map.set(event.id, [posX, posY, eventWidth.value, eventHeight.value]);
+ map.set(event.id, [minorOffset, majorOffset, eventWidth.value, eventHeight.value]);
} else {
- map.set(event.id, [posY, posX, eventWidth.value, eventHeight.value]);
+ map.set(event.id, [majorOffset, minorOffset, eventWidth.value, eventHeight.value]);
}
// Update to next position
- posY += eventMajorSz.value + SPACING;
+ majorOffset += eventMajorSz.value + SPACING;
}
// If more events could be displayed, notify parent
if (!full){
@@ -353,6 +353,8 @@ const idToPos = computed(() => {
//
return map;
});
+
+// For event lines
type LineCoords = [number, number, number, number];
const eventLines: ShallowRef<Map<number, LineCoords>> = shallowRef(new Map());
// Maps event ID to event line data (x, y, length, and angle)