首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >日历日期排序:职业概览

日历日期排序:职业概览
EN

Stack Overflow用户
提问于 2021-10-26 11:54:45
回答 3查看 115关注 0票数 0

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

现在,我已经使用moment.js在日历上获得了事件,因此它们的格式如下(在开始日期排序):

代码语言:javascript
复制
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数组应该如下所示:

代码语言:javascript
复制
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
},]

老实说,我不知道如何将日历事件分组,因此它们返回一个数组,其中包含开始时间和结束时间,结果出现了红色框。

有谁能帮我解决这个问题吗?谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-27 07:07:13

在“RobG”的帮助下,我找到了答案。以下是我对感兴趣的人的回答:

代码语言:javascript
复制
// 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)
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

票数 0
EN

Stack Overflow用户

发布于 2021-10-26 14:00:12

根据更新的问题,对保留开始和结束属性的所有日期进行排序。按照顺序处理它们,以便第一个日期(必须是开始日期)开始级别1,这是单一预订的。

如果下一次约会结束了,那就结束吧。但是,如果下一个日期是开始,则会增加级别(即双重预订)。下面是一个实现,您可能希望按级别或开始日期对条形图进行排序。

下面的函数首先获取所有的日期,并按照它们的类型开始或结束按升序排序。然后处理每个日期-开始日期创建一个新的栏,结束日期结束最近的栏。当结束时,最后一个栏会弹出开始并添加到条形图中,这是一个已完成的条形图的数组。

这取决于源数据是否有效,即它必须以开始开始,以结束结束,它们必须以正确的顺序和相同的数目。

一种改进是确保在开始和结束日期相同的情况下,开始总是在结束之前排序,所以零长度事件(里程碑?)不要得到有序的结束-启动,这会导致级别在增加之前减少。可能有其他问题的开始和结束有相同的日期和时间,请测试。

代码语言:javascript
复制
// 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格式,那么它们可以作为字符串排序,而无需转换为日期。

票数 1
EN

Stack Overflow用户

发布于 2021-10-26 12:04:43

看起来您需要在毫秒内获得diff,并从最大到最少进行排序。您必须使用这个来查看它的排序方式(可能需要在diff语句上翻转'a‘和'b’,因为我没有针对您的数组运行它)

代码语言:javascript
复制
const sortedArray = array.sort((a, b) => a.diff(b))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69722644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档