代码中的数学(1)- 交集

背景

公司要求做日程模块的移动端展示,当天日程按照时间轴加载出来,单个时间端占满宽度,两个日程冲突时平分宽度。

思路

  1. 写出时间轴做背景单个高度为40px
  2. 日程用绝对定位加载高度为日程时长(例如:11:00-13:00时长为2小时)公式为
(beginTime.getTime()-endTime.getTime())/1000/60/60*40
  1. 同理Top为11:00与00:00的差
  2. 宽度为展示区域的宽度,同一时间段日程平分即 宽度除以同一时间的日程数
  3. Left为 固定的居左距离+(左侧冲突日程数-1)*平均宽度

注意点

  1. 注意因为只展示今日的跨天日程如(2019-10-14 18:00 ~ 2019-10-15 08:00)开始时间统一处理为2019-10-15 00:00
  2. 同一时间日程有可能冲突
  3. 宽度不是固定的如:8:00 - 10:00、12:00-15:00 、13:00-16:00 展示形状应该是一个“T”形

代码简述

核心代码目的把日程按照时间不冲突分成多列

this.daydata.forEach(itm => {
        const todayBegin = this.daydata.date.getTime()
        const todayEnd = this.daydata.date.getTime() + (24 * 60 * 60 * 1000)
        const realBegin = itm.realStartTime.getTime()
        const realEnd = itm.realEndTime.getTime()
        // 只保留当日的时间范围
        itm.todayBegin = (todayBegin > realBegin ? todayBegin : realBegin)
        itm.todayEnd = (realEnd > todayEnd ? todayEnd : realEnd)
        // 是否创建新列
        let add = true
        clos.forEach(it => {
          // 是否有交集,有交集创建新列,无交集拼接 此时数据会出现重复
          let intersection = false
          it.forEach(i => {
            if ((i.todayEnd > itm.todayBegin && i.todayEnd < itm.todayEnd) || (i.todayBegin < itm.todayBegin && i.todayEnd > itm.todayEnd) || (i.todayBegin > itm.todayBegin && i.todayBegin < itm.todayEnd)) {
              intersection = true
            }
          })
          if (!intersection) {
            add = false
            it.push(itm)
          }
        })
        if (add) {
          clos.push([itm])
        }
      })

最初算法

/**判断所有可能相交的情况
  * 1. A[1,5], B[4,8] A尾部与B首部相交(A1端必须在[B1,B2]之间)
  * 2. A[1,5], B[2,4] A包含B(B的两个端点都位于A中)
  * 3. A[2,5], B[1,3] A首部与B尾部相交(A1端必须在[B1,B2]之间)
  * 4. A[4,5], B[1,8] A被包含于B (同2)
  **/
 if ((i.todayEnd > itm.todayBegin && i.todayEnd < itm.todayEnd) || (i.todayBegin < itm.todayBegin && i.todayEnd > itm.todayEnd) || (i.todayBegin > itm.todayBegin && i.todayBegin < itm.todayEnd)) {
              intersection = true
 }

算法优化:

  it.forEach(i => {
      if (Math.max(i.todayBegin, itm.todayBegin) < Math.min(i.todayEnd, itm.todayEnd)) {
       intersection = true
      }
   })
          

数据分列后时间上不再冲突,合并重复数据,计算宽度根据定位加载数据

饮水思源

  • 判断两个区间有无交集

你可能感兴趣的:(代码中的数学(1)- 交集)