Merge pull request #76 from ok2/codex/fix-event-width-and-color-handling
Improve event overlap display
This commit is contained in:
commit
8451fa9f54
19
events.js
19
events.js
@ -12,15 +12,16 @@
|
||||
// duration - optional length of the event in seconds.
|
||||
// showMega - optional boolean, show label on the megasequence view (default true).
|
||||
// showDetail - optional boolean, show event in the detail view (default true).
|
||||
// color - optional hex color for the event (used in detail view)
|
||||
|
||||
window.SPECIAL_EVENTS = [
|
||||
{ cobie: '49f4.9332', label: 'Afina', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '11e5.f552', label: 'Oleks', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '4d07.a2b2', label: 'Vincent', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '3edc.d430', label: 'Hochzeitstag', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '330d.d4ae', label: 'Zusammentag', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '11de.0c52', label: 'Anna', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '467f.ae61', label: 'Iris', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '6854.7a75', label: 'Sleep', unit: 'second', interval: 86400, duration: 28800, showMega: false },
|
||||
{ cobie: '6854.9695', label: 'Night', unit: 'second', interval: 86400, duration: 28800, showMega: false, shiftWithTimezone: true }
|
||||
{ cobie: '49f4.9332', label: 'Afina', color: '#e57373', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '11e5.f552', label: 'Oleks', color: '#64b5f6', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '4d07.a2b2', label: 'Vincent', color: '#81c784', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '3edc.d430', label: 'Hochzeitstag', color: '#ffb74d', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '330d.d4ae', label: 'Zusammentag', color: '#ba68c8', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '11de.0c52', label: 'Anna', color: '#4db6ac', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '467f.ae61', label: 'Iris', color: '#7986cb', unit: 'cosmocycle', interval: 1 },
|
||||
{ cobie: '6854.7a75', label: 'Sleep', color: '#546e7a', unit: 'second', interval: 86400, duration: 28800, showMega: false },
|
||||
{ cobie: '6854.9695', label: 'Night', color: '#212121', unit: 'second', interval: 86400, duration: 28800, showMega: false, shiftWithTimezone: true }
|
||||
];
|
||||
|
||||
60
script.js
60
script.js
@ -44,6 +44,36 @@ let updateInterval;
|
||||
let lastRenderedEonstrip = null;
|
||||
let currentDetailCob = null;
|
||||
|
||||
function hexToRgba(hex, alpha) {
|
||||
if (!hex) return '';
|
||||
let c = hex.replace('#', '');
|
||||
if (c.length === 3) {
|
||||
c = c.split('').map(x => x + x).join('');
|
||||
}
|
||||
const r = parseInt(c.substring(0,2),16);
|
||||
const g = parseInt(c.substring(2,4),16);
|
||||
const b = parseInt(c.substring(4,6),16);
|
||||
return `rgba(${r},${g},${b},${alpha})`;
|
||||
}
|
||||
|
||||
function getContrastColor(hex) {
|
||||
if (!hex) return '#fff';
|
||||
let c = hex.replace('#','');
|
||||
if (c.length === 3) c = c.split('').map(x=>x+x).join('');
|
||||
const r = parseInt(c.substr(0,2),16);
|
||||
const g = parseInt(c.substr(2,2),16);
|
||||
const b = parseInt(c.substr(4,2),16);
|
||||
const yiq = (r*299 + g*587 + b*114) / 1000;
|
||||
return yiq >= 128 ? '#000' : '#fff';
|
||||
}
|
||||
|
||||
function applyEventColors(elem, color, alpha) {
|
||||
if (!color || !elem) return;
|
||||
elem.style.setProperty('--bg-color', hexToRgba(color, alpha));
|
||||
elem.style.setProperty('--border-color', color);
|
||||
elem.style.setProperty('--text-color', getContrastColor(color));
|
||||
}
|
||||
|
||||
function getTimezoneOffsetSeconds(date) {
|
||||
if (currentTimezone === 'UTC') return 0;
|
||||
if (currentTimezone === 'TAI') return getTAIOffsetAt(date);
|
||||
@ -761,6 +791,7 @@ function showEonstripDetail(index, startCob) {
|
||||
const relEnd = (occ + duration - start) / COBIE_UNITS.eonstrip;
|
||||
events.push({
|
||||
label: ev.label,
|
||||
color: ev.color,
|
||||
start: relStart,
|
||||
end: relEnd,
|
||||
cobStart: occ,
|
||||
@ -772,16 +803,30 @@ function showEonstripDetail(index, startCob) {
|
||||
}
|
||||
});
|
||||
events.sort((a,b)=>a.start-b.start);
|
||||
const columns = [];
|
||||
|
||||
const groups = [];
|
||||
let active = [];
|
||||
events.forEach(ev=>{
|
||||
active = active.filter(a=>a.end>ev.start);
|
||||
if (active.length===0) {
|
||||
groups.push({events:[],columns:[],maxCols:0});
|
||||
}
|
||||
const g = groups[groups.length-1];
|
||||
let col=0;
|
||||
while(columns[col] && columns[col] > ev.start) col++;
|
||||
columns[col] = ev.end;
|
||||
while(g.columns[col] && g.columns[col] > ev.start) col++;
|
||||
g.columns[col] = ev.end;
|
||||
ev.col = col;
|
||||
g.maxCols = Math.max(g.maxCols, col+1);
|
||||
g.events.push(ev);
|
||||
active.push(ev);
|
||||
});
|
||||
const width = 100 / (columns.length || 1);
|
||||
groups.forEach(g=>{
|
||||
const width = 100/(g.maxCols||1);
|
||||
g.events.forEach(ev=>ev.width=width);
|
||||
});
|
||||
|
||||
events.forEach(ev=>{
|
||||
const left = ev.col * width;
|
||||
const left = ev.col * ev.width;
|
||||
const displayStart = Math.max(0, ev.start);
|
||||
const displayEnd = Math.min(1, ev.end);
|
||||
const elem = document.createElement('div');
|
||||
@ -799,7 +844,9 @@ function showEonstripDetail(index, startCob) {
|
||||
}
|
||||
elem.style.top = (displayStart * 100) + '%';
|
||||
elem.style.left = `calc(var(--scale-width) + ${left}%)`;
|
||||
elem.style.width = `calc(${width}% - 2px)`;
|
||||
elem.style.width = `calc(${ev.width}% - 2px)`;
|
||||
|
||||
if (ev.color) applyEventColors(elem, ev.color, 0.4);
|
||||
|
||||
if (elem.classList.contains('small-event') || elem.className === 'event-line') {
|
||||
const label = document.createElement('span');
|
||||
@ -809,6 +856,7 @@ function showEonstripDetail(index, startCob) {
|
||||
}
|
||||
label.textContent = ev.label;
|
||||
elem.appendChild(label);
|
||||
if (ev.color) applyEventColors(label, ev.color, 0.5);
|
||||
} else {
|
||||
elem.textContent = ev.label;
|
||||
}
|
||||
|
||||
14
style.css
14
style.css
@ -441,11 +441,11 @@
|
||||
.event-box, .event-line {
|
||||
position: absolute;
|
||||
left: var(--scale-width);
|
||||
background: rgba(255,0,255,0.4);
|
||||
border: 1px solid rgba(0,255,255,0.7);
|
||||
background: var(--bg-color, rgba(255,0,255,0.4));
|
||||
border: 1px solid var(--border-color, rgba(0,255,255,0.7));
|
||||
border-radius: 4px;
|
||||
padding: 2px 4px;
|
||||
color: #fff;
|
||||
color: var(--text-color, #fff);
|
||||
font-size: 0.75em;
|
||||
overflow: visible;
|
||||
white-space: nowrap;
|
||||
@ -476,15 +476,15 @@
|
||||
left: 50%;
|
||||
transform: translate(-50%, -2px);
|
||||
margin-bottom: 2px;
|
||||
background: rgba(255,0,255,0.5);
|
||||
border: 1px solid rgba(0,255,255,0.8);
|
||||
background: var(--bg-color, rgba(255,0,255,0.5));
|
||||
border: 1px solid var(--border-color, rgba(0,255,255,0.8));
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
color: var(--text-color, #fff);
|
||||
font-size: 0.75em;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 0 4px #ff00ff;
|
||||
text-shadow: 0 0 4px var(--border-color, #ff00ff);
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user