gpt4 book ai didi

javascript - session 日历 |如何处理在日历中显示的重叠 session ?

转载 作者:行者123 更新时间:2023-11-30 16:04:01 25 4
gpt4 key购买 nike

抱歉这个问题太长了。

我尝试在日历上创建一天的 session 。我需要帮助来处理重叠的间隔。

我写的代码如下:

HTML

<body>
<div id="timeline"></div>
<div id="calendar" class="calendar">
</div>
</body>

CSS

.calendar {
border: 1px solid black;
position: absolute;
width: 600px;
height: 1440px;
left: 60px;
}

.event {
position: absolute;
float: left;
width: 100%;
overflow: auto;
border: 0px solid red;
}

#timeline {
position: absolute;
float: left;
}

JS

function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}

function creatTimeline(tl) {
var i = 0;
while (i < tl.length) {
var divEl = document.createElement('div');
divEl.style.width = '50px';
divEl.style.height = '120px';
divEl.style.border = '0px solid yellow';
divEl.innerHTML = tl[i];
var timeLine = document.getElementById('timeline');
timeLine.appendChild(divEl);
i++;
}
}

function appendEventDivs(eventArr) {
var i = 0;
while (i < eventArr.length) {
var eventEl = document.createElement('div');
eventEl.className = 'event';
eventEl.style.height = eventArr[i].height;
eventEl.style.top = eventArr[i].top;
eventEl.style.background = eventArr[i].color;
eventEl.style.width = eventArr[i].width;
eventEl.style.left = eventArr[i].left;
eventEl.innerHTML = 'Meeting' + eventArr[i].id;
var cl = document.getElementById('calendar');
cl.appendChild(eventEl);
i++;
}
}

function collidesWith(a, b) {
return a.end > b.start && a.start < b.end;
}

function checkCollision(eventArr) {
for (var i = 0; i < eventArr.length; i++) {
eventArr[i].cols = [];
for (var j = 0; j < eventArr.length; j++) {
if (collidesWith(eventArr[i], eventArr[j])) {
eventArr[i].cols.push(i);
}
}
}

return eventArr;
}

function updateEvents(eventArr) {
eventArr = checkCollision(eventArr);
var arr = [];
arr = eventArr.map(function(el) {
//just to differentiate each event with different colours
el.color = getRandomColor();

el.height = (el.end - el.start) * 2 + 'px';
el.top = (el.start) * 2 + 'px';
el.width = (600 / el.cols.length) + 'px';
return el;
});
return arr;
}

var events = [{
id: 123,
start: 60,
end: 150
}, {
id: 124,
start: 540,
end: 570
}, {
id: 125,
start: 555,
end: 600
}, {
id: 126,
start: 585,
end: 660
}];

var timeline = ['9AM', '10AM', '11AM', '12Noon', '1PM', '2PM', '3PM', '4PM', '5PM', '6PM', '7PM', '8PM', '9PM'];

function getEvents (eventArr) {
eventArr.sort(function(a, b) {
return a.start - b.start;
});
eventArr = updateEvents(eventArr);
appendEventDivs(eventArr);
console.log(eventArr);
//PART 1 - function returning the eventArr with all the required attributes
return eventArr;
};

creatTimeline(timeline);
getEvents(events);

工作 fiddle here

任何人都可以指导我如何处理重叠间隔,以便它们并排出现而不是彼此重叠。

提前致谢。

最佳答案

您需要弄清楚每个事件应该在哪一列,然后才能确定它们的宽度或左侧位置。为此,您还需要存储在每个事件之前发生的碰撞事件:

function checkCollision(eventArr) {
for (var i = 0; i < eventArr.length; i++) {
eventArr[i].cols = [];
eventArr[i].colsBefore=[];
for (var j = 0; j < eventArr.length; j++) {
if (collidesWith(eventArr[i], eventArr[j])) {
eventArr[i].cols.push(j);
if(i>j) eventArr[i].colsBefore.push(j); //also list which of the conflicts came before
}
}
}
return eventArr;
}

现在,我们可以找出每个事件的列。一旦我们这样做了,我们就可以计算出它们应该有多宽,并且水平定位应该很容易。这应该在您的 updateEvents 函数中完成。我在下面的代码注释中有更详细的解释。

function updateEvents(eventArr) {
eventArr = checkCollision(eventArr);
var arr=eventArr.slice(0); //clone the array
for(var i=0; i<arr.length; i++){
var el=arr[i];
el.color = getRandomColor();
el.height = (el.end - el.start) * 2 + 'px';
el.top = (el.start) * 2 + 'px';

if(i>0 && el.colsBefore.length>0){ //check column if not the first event and the event has collisions with prior events
if(arr[i-1].column>0){ //if previous event wasn't in the first column, there may be space to the left of it
for(var j=0;j<arr[i-1].column;j++){ //look through all the columns to the left of the previous event
if(el.colsBefore.indexOf(i-(j+2))===-1){ //the current event doesn't collide with the event being checked...
el.column=arr[i-(j+2)].column; //...and can be put in the same column as it
}
}
if(typeof el.column==='undefined') el.column=arr[i-1].column+1; //if there wasn't any free space, but it ito the right of the previous event
}else{
var column=0;
for(var j=0;j<el.colsBefore.length;j++){ //go through each column to see where's space...
if(arr[el.colsBefore[el.colsBefore.length-1-j]].column==column) column++;
}
el.column=column;
}
}else el.column=0;
}
//We need the column for every event before we can determine the appropriate width and left-position, so this is in a different for-loop:
for(var i=0; i<arr.length; i++){
arr[i].totalColumns=0;
if(arr[i].cols.length>1){ //if event collides
var conflictGroup=[]; //store here each column in the current event group
var conflictingColumns=[]; //and here the column of each of the events in the group
addConflictsToGroup(arr[i]);
function addConflictsToGroup(a){
for(k=0;k<a.cols.length;k++){
if(conflictGroup.indexOf(a.cols[k])===-1){ //don't add same event twice to avoid infinite loop
conflictGroup.push(a.cols[k]);
conflictingColumns.push(arr[a.cols[k]].column);
addConflictsToGroup(arr[a.cols[k]]); //check also the events this event conflicts with
}
}
}
arr[i].totalColumns=Math.max.apply(null, conflictingColumns); //set the greatest value as number of columns
}
arr[i].width=(600/(arr[i].totalColumns+1))+'px';
arr[i].left=(600/(arr[i].totalColumns+1)*arr[i].column)+'px';
}
return arr;
}

工作 fiddle :https://jsfiddle.net/ilpo/ftbjan06/5/我添加了一些其他事件来测试不同的场景。

哦,顺便说一句,绝对定位的元素不能 float

关于javascript - session 日历 |如何处理在日历中显示的重叠 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37302106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com