瀏覽代碼

change how we interface with DaySeries

Adam Shaw 7 年之前
父節點
當前提交
c1588b9631
共有 3 個文件被更改,包括 57 次插入37 次删除
  1. 1 1
      src/agenda/TimeGridSlicer.ts
  2. 16 31
      src/basic/DayGridSlicer.ts
  3. 40 5
      src/common/DaySeries.ts

+ 1 - 1
src/agenda/TimeGridSlicer.ts

@@ -15,7 +15,7 @@ export default class TimeGridSlicer {
 
   constructor(dateProfile: DateProfile, dateProfileGenerator: DateProfileGenerator, isRtl: boolean, dateEnv: DateEnv) {
     this.dateProfile = dateProfile
-    this.daySeries = new DaySeries(dateProfile, dateProfileGenerator)
+    this.daySeries = new DaySeries(dateProfile.renderRange, dateProfileGenerator)
     this.dateRanges = this.daySeries.dates.map(function(dayDate) {
       return {
         start: dateEnv.add(dayDate, dateProfile.minTime),

+ 16 - 31
src/basic/DayGridSlicer.ts

@@ -16,7 +16,7 @@ export default class DayGridSlicer {
 
 
   constructor(dateProfile: DateProfile, dateProfileGenerator: DateProfileGenerator, isRtl: boolean, breakOnWeeks: boolean) {
-    let daySeries = new DaySeries(dateProfile, dateProfileGenerator)
+    let daySeries = new DaySeries(dateProfile.renderRange, dateProfileGenerator)
     let { dates } = daySeries
     let daysPerRow
     let firstDay
@@ -73,43 +73,28 @@ export default class DayGridSlicer {
   }
 
 
-  // Slices up a date range into a segment for every week-row it intersects with
-  // range already normalized to start-of-day
   sliceRangeByRow(range) {
-    let daysPerRow = this.daysPerRow
-    let rangeFirst = this.daySeries.getDateDayIndex(range.start) // inclusive first index
-    let rangeLast = this.daySeries.getDateDayIndex(addDays(range.end, -1)) // inclusive last index
+    let { daysPerRow } = this
+    let seriesSeg = this.daySeries.sliceRange(range)
     let segs = []
-    let row
-    let rowFirst
-    let rowLast // inclusive day-index range for current row
-    let segFirst
-    let segLast // inclusive day-index range for segment
 
-    for (row = 0; row < this.rowCnt; row++) {
-      rowFirst = row * daysPerRow
-      rowLast = rowFirst + daysPerRow - 1
+    if (seriesSeg) {
+      let { firstIndex, lastIndex } = seriesSeg
+      let index = firstIndex
 
-      // intersect segment's offset range with the row's
-      segFirst = Math.max(rangeFirst, rowFirst)
-      segLast = Math.min(rangeLast, rowLast)
+      while (index <= lastIndex) {
+        let row = Math.floor(index / daysPerRow)
+        let nextIndex = Math.min((row + 1) * daysPerRow, lastIndex + 1)
 
-      // deal with in-between indices
-      segFirst = Math.ceil(segFirst) // in-between starts round to next cell
-      segLast = Math.floor(segLast) // in-between ends round to prev cell
-
-      if (segFirst <= segLast) { // was there any intersection with the current row?
         segs.push({
-          row: row,
-
-          // normalize to start of row
-          firstRowDayIndex: segFirst - rowFirst,
-          lastRowDayIndex: segLast - rowFirst,
-
-          // must be matching integers to be the segment's start/end
-          isStart: segFirst === rangeFirst,
-          isEnd: segLast === rangeLast
+          row,
+          firstRowDayIndex: index % daysPerRow,
+          lastRowDayIndex: (nextIndex - 1) % daysPerRow,
+          isStart: seriesSeg.isStart && index === firstIndex,
+          isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex
         })
+
+        index = nextIndex
       }
     }
 

+ 40 - 5
src/common/DaySeries.ts

@@ -1,14 +1,25 @@
-import DateProfileGenerator, { DateProfile } from '../DateProfileGenerator'
+import DateProfileGenerator from '../DateProfileGenerator'
 import { DateMarker, addDays, diffDays } from '../datelib/marker'
+import { DateRange } from '../datelib/date-range'
+
+export interface DaySeriesSeg {
+  firstIndex: number
+  lastIndex: number
+  isStart: boolean
+  isEnd: boolean
+}
 
 export default class DaySeries {
 
+  cnt: number
+
+  // TODO: make private
   dates: DateMarker[] // whole-day dates for each column. left to right
   indices: number[] // for each day from start, the offset
 
-  constructor(dateProfile: DateProfile, dateProfileGenerator: DateProfileGenerator) {
-    let date: DateMarker = dateProfile.renderRange.start
-    let end: DateMarker = dateProfile.renderRange.end
+  constructor(range: DateRange, dateProfileGenerator: DateProfileGenerator) {
+    let date: DateMarker = range.start
+    let end: DateMarker = range.end
     let indices: number[] = []
     let dates: DateMarker[] = []
     let dayIndex = -1
@@ -26,6 +37,30 @@ export default class DaySeries {
 
     this.dates = dates
     this.indices = indices
+    this.cnt = dates.length
+  }
+
+  sliceRange(range: DateRange): DaySeriesSeg | null {
+    let firstIndex = this.getDateDayIndex(range.start) // inclusive first index
+    let lastIndex = this.getDateDayIndex(addDays(range.end, -1)) // inclusive last index
+
+    let clippedFirstIndex = Math.max(0, firstIndex)
+    let clippedLastIndex = Math.min(this.cnt - 1, lastIndex)
+
+    // deal with in-between indices
+    clippedFirstIndex = Math.ceil(clippedFirstIndex) // in-between starts round to next cell
+    clippedLastIndex = Math.floor(clippedLastIndex) // in-between ends round to prev cell
+
+    if (clippedFirstIndex <= clippedLastIndex) {
+      return {
+        firstIndex: clippedFirstIndex,
+        lastIndex: clippedLastIndex,
+        isStart: firstIndex === clippedFirstIndex,
+        isEnd: lastIndex === clippedLastIndex
+      }
+    } else {
+      return null
+    }
   }
 
   // Given a date, returns its chronolocial cell-index from the first cell of the grid.
@@ -33,7 +68,7 @@ export default class DaySeries {
   // If before the first offset, returns a negative number.
   // If after the last offset, returns an offset past the last cell offset.
   // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
-  getDateDayIndex(date: DateMarker) {
+  private getDateDayIndex(date: DateMarker) {
     let indices = this.indices
     let dayOffset = Math.floor(diffDays(this.dates[0], date))