我正在开发一个日历插件,它将显示我的职业概述,如下所示:

现在,我已经使用moment.js在日历上获得了事件,因此它们的格式如下(在开始日期排序):
let events = [{
name: 'Event A',
start: '01-11-2021 00:00',
end: '08-11-2021 00:00',
},{
name: 'Event C',
start: '03-11-2021 00:00',
end: '06-11-2021 00:00',
},{
name: 'Event E',
start: '05-11-2021 00:00',
end: '08-11-2021 00:00',
},{
name: 'Event D',
start: '07-11-2021 00:00',
end: '12-11-2021 00:00',
},{
name: 'Event B',
start: '10-11-2021 00:00',
end: '17-11-2021 00:00',
},]预期的occupationOverview数组应该如下所示:
let ooArray = [
{ // Longest/bottom bar
start: '01-11-2021 00:00',
end: '17-11-2021 00:00',
group: 1
},
{ // Middle bar 1
start: '03-11-2021 00:00',
end: '08-11-2021 00:00',
group: 2
},
{ // Middle bar 2
start: '10-11-2021 00:00',
end: '12-11-2021 00:00',
group: 2
},
{ // Top bar 1
start: '05-11-2021 00:00',
end: '06-11-2021 00:00',
group: 3
},
{ // Top bar 2
start: '07-11-2021 00:00',
end: '08-11-2021 00:00',
group: 3
},]老实说,我不知道如何将日历事件分组,因此它们返回一个数组,其中包含开始时间和结束时间,结果出现了红色框。
有谁能帮我解决这个问题吗?谢谢!
发布于 2021-10-27 07:07:13
在“RobG”的帮助下,我找到了答案。以下是我对感兴趣的人的回答:
// Not needed for answer, but result gave warnings so yeah
moment.suppressDeprecationWarnings = true;
let newItems = []
let dateArray = []
let events = [{
name: 'Event A',
start: '01-11-2021 00:00',
end: '08-11-2021 00:00',
},{
name: 'Event C',
start: '03-11-2021 00:00',
end: '06-11-2021 00:00',
},{
name: 'Event E',
start: '05-11-2021 00:00',
end: '08-11-2021 00:00',
},{
name: 'Event D',
start: '07-11-2021 00:00',
end: '12-11-2021 00:00',
},{
name: 'Event B',
start: '10-11-2021 00:00',
end: '17-11-2021 00:00',
},]
// Make one big array with all start and end dates
events.forEach(event=> {
dateArray.push({
type: 'start',
date: event.start
}, {
type: 'end',
date: event.end
})
})
// Sort the dates from first to last
dateArray = dateArray.sort((left, right) => {
return moment(left.date).diff(moment(right.date))
})
let groupID = -1
// Loop through the array with all dates and add them to a group
// based on if the current date is a start or end
for (let i = 0; i < dateArray.length; i++) {
if (dateArray[i].type === 'start') groupID++
else groupID--
for (let ii = 0; ii <= groupID; ii++) {
if (dateArray[i + 1] &&
!moment(dateArray[i].date).isSame(dateArray[i + 1].date)) {
newItems.push({
group: 1,
start: dateArray[i].date,
end: dateArray[i + 1].date,
subgroup: 'sg_' + ii,
subgroupOrder: ii
})
}
}
}
console.log(newItems)<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
发布于 2021-10-26 14:00:12
根据更新的问题,对保留开始和结束属性的所有日期进行排序。按照顺序处理它们,以便第一个日期(必须是开始日期)开始级别1,这是单一预订的。
如果下一次约会结束了,那就结束吧。但是,如果下一个日期是开始,则会增加级别(即双重预订)。下面是一个实现,您可能希望按级别或开始日期对条形图进行排序。
下面的函数首先获取所有的日期,并按照它们的类型开始或结束按升序排序。然后处理每个日期-开始日期创建一个新的栏,结束日期结束最近的栏。当结束时,最后一个栏会弹出开始并添加到条形图中,这是一个已完成的条形图的数组。
这取决于源数据是否有效,即它必须以开始开始,以结束结束,它们必须以正确的顺序和相同的数目。
一种改进是确保在开始和结束日期相同的情况下,开始总是在结束之前排序,所以零长度事件(里程碑?)不要得到有序的结束-启动,这会导致级别在增加之前减少。可能有其他问题的开始和结束有相同的日期和时间,请测试。
// Parse date in D-M-Y H:m format
function parseDMY(s) {
let [D, M, Y, H, m] = s.split(/\D/);
return new Date(Y, M - 1, D, H, m);
}
// Format as DD-MM-YYYY HH:mm
function formatDate(d) {
let z = n => ('0'+n).slice(-2);
return `${z(d.getDate())}-${z(d.getMonth()+1)}-${d.getFullYear()} ` +
`${z(d.getHours())}:${z(d.getMinutes())}`;
}
// Generates "occupation" bars
function calcBookingLevels(events) {
// Get sorted array of [{type, Date}]
let dates = events.reduce( (dates, event) => {
dates.push({type: 'start', date: parseDMY(event.start)},
{type: 'end', date: parseDMY(event.end)});
return dates;
}, []).sort((a, b) => a.date - b.date);
// Process dates to get occupation bars with levels
let bars = [];
let starts = [];
let level = 0;
dates.forEach(date => {
// If it's a start, start a new bar
if (date.type == 'start') {
let bar = {level: ++level, start: formatDate(date.date)};
starts.push(bar);
// Otherwise it's an end, close the most recent bar and
// move to bars array
} else {
let t = starts.pop();
t.end = formatDate(date.date);
--level;
bars.push(t);
}
})
return bars;
}
// Sample data
let events = [{
name: 'Event A',
start: '01-11-2021 00:00',
end: '08-11-2021 00:00',
},{
name: 'Event C',
start: '03-11-2021 00:00',
end: '06-11-2021 00:00',
},{
name: 'Event E',
start: '05-11-2021 00:00',
end: '08-11-2021 00:00',
},{
name: 'Event D',
start: '07-11-2021 00:00',
end: '12-11-2021 00:00',
},{
name: 'Event B',
start: '10-11-2021 00:00',
end: '17-11-2021 00:00',
},];
// Run it...
console.log(calcBookingLevels(events));
如果日期是YYYY DD:mm格式,那么它们可以作为字符串排序,而无需转换为日期。
发布于 2021-10-26 12:04:43
看起来您需要在毫秒内获得diff,并从最大到最少进行排序。您必须使用这个来查看它的排序方式(可能需要在diff语句上翻转'a‘和'b’,因为我没有针对您的数组运行它)
const sortedArray = array.sort((a, b) => a.diff(b))https://stackoverflow.com/questions/69722644
复制相似问题