Improves event grid layout logic
Refines the event grid layout algorithm to more accurately identify conflicting events for stacking within the grid. Now uses an expanding search to find chains of conflicting events, ensuring that all events that should be grouped together are correctly identified.
This commit is contained in:
parent
06356df2a3
commit
b590467f60
3 changed files with 51 additions and 7 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 10 KiB |
11
.workbench/scenarie9.html
Normal file
11
.workbench/scenarie9.html
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<swp-event-group class="cols-2 stack-level-0" data-stack-link="{"stackLevel":0}" style="top: 481px; margin-left: 0px; z-index: 100;"><div style="position: relative;"><swp-event data-event-id="S9A" data-title="Scenario 9: Event A" data-start="2025-10-09T10:00:00.000Z" data-end="2025-10-09T11:00:00.000Z" data-type="work" data-duration="60" style="position: absolute; top: 0px; height: 77px; left: 0px; right: 0px;">
|
||||||
|
<swp-event-time data-duration="60">12:00 - 13:00</swp-event-time>
|
||||||
|
<swp-event-title>Scenario 9: Event A</swp-event-title>
|
||||||
|
</swp-event></div><div style="position: relative;"><swp-event data-event-id="S9B" data-title="Scenario 9: Event B" data-start="2025-10-09T10:30:00.000Z" data-end="2025-10-09T11:30:00.000Z" data-type="work" data-duration="60" style="position: absolute; top: 40px; height: 77px; left: 0px; right: 0px;">
|
||||||
|
<swp-event-time data-duration="60">12:30 - 13:30</swp-event-time>
|
||||||
|
<swp-event-title>Scenario 9: Event B</swp-event-title>
|
||||||
|
</swp-event></div></swp-event-group>
|
||||||
|
<swp-event data-event-id="S9C" data-title="Scenario 9: Event C" data-start="2025-10-09T11:15:00.000Z" data-end="2025-10-09T13:00:00.000Z" data-type="work" data-duration="105" data-stack-link="{"stackLevel":1}" style="position: absolute; top: 581px; height: 137px; left: 2px; right: 2px; margin-left: 15px; z-index: 101;">
|
||||||
|
<swp-event-time data-duration="105">13:15 - 15:00</swp-event-time>
|
||||||
|
<swp-event-title>Scenario 9: Event C</swp-event-title>
|
||||||
|
</swp-event>
|
||||||
|
|
@ -54,18 +54,51 @@ export class EventLayoutCoordinator {
|
||||||
const firstEvent = remaining[0];
|
const firstEvent = remaining[0];
|
||||||
|
|
||||||
// Find events that could be in GRID with first event
|
// Find events that could be in GRID with first event
|
||||||
// (start within threshold AND overlap)
|
// Use expanding search to find chains (A→B→C where each conflicts with next)
|
||||||
const gridSettings = calendarConfig.getGridSettings();
|
const gridSettings = calendarConfig.getGridSettings();
|
||||||
const thresholdMinutes = gridSettings.gridStartThresholdMinutes;
|
const thresholdMinutes = gridSettings.gridStartThresholdMinutes;
|
||||||
|
|
||||||
const gridCandidates = [firstEvent];
|
const gridCandidates = [firstEvent];
|
||||||
|
let candidatesChanged = true;
|
||||||
|
|
||||||
|
// Keep expanding until no new candidates can be added
|
||||||
|
while (candidatesChanged) {
|
||||||
|
candidatesChanged = false;
|
||||||
|
|
||||||
for (let i = 1; i < remaining.length; i++) {
|
for (let i = 1; i < remaining.length; i++) {
|
||||||
const candidate = remaining[i];
|
const candidate = remaining[i];
|
||||||
const startDiff = Math.abs(candidate.start.getTime() - firstEvent.start.getTime()) / (1000 * 60);
|
|
||||||
|
|
||||||
// Only add if starts within threshold AND overlaps with firstEvent
|
// Skip if already in candidates
|
||||||
if (startDiff <= thresholdMinutes && this.stackManager.doEventsOverlap(firstEvent, candidate)) {
|
if (gridCandidates.includes(candidate)) continue;
|
||||||
|
|
||||||
|
// Check if candidate conflicts with ANY event in gridCandidates
|
||||||
|
for (const existingCandidate of gridCandidates) {
|
||||||
|
let hasConflict = false;
|
||||||
|
|
||||||
|
// Check 1: Start-to-start conflict (starts within threshold)
|
||||||
|
const startToStartDiff = Math.abs(candidate.start.getTime() - existingCandidate.start.getTime()) / (1000 * 60);
|
||||||
|
if (startToStartDiff <= thresholdMinutes && this.stackManager.doEventsOverlap(candidate, existingCandidate)) {
|
||||||
|
hasConflict = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check 2: End-to-start conflict (candidate starts within threshold before existingCandidate ends)
|
||||||
|
const endToStartMinutes = (existingCandidate.end.getTime() - candidate.start.getTime()) / (1000 * 60);
|
||||||
|
if (endToStartMinutes > 0 && endToStartMinutes <= thresholdMinutes) {
|
||||||
|
hasConflict = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check 3: Reverse end-to-start (existingCandidate starts within threshold before candidate ends)
|
||||||
|
const reverseEndToStart = (candidate.end.getTime() - existingCandidate.start.getTime()) / (1000 * 60);
|
||||||
|
if (reverseEndToStart > 0 && reverseEndToStart <= thresholdMinutes) {
|
||||||
|
hasConflict = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasConflict) {
|
||||||
gridCandidates.push(candidate);
|
gridCandidates.push(candidate);
|
||||||
|
candidatesChanged = true;
|
||||||
|
break; // Found conflict, move to next candidate
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue